Skip to content

Commit bdd3ec5

Browse files
refactor(cc-addon-info): use the new client
Remove hardcoded endpoints and use the new client instead
1 parent 95a805f commit bdd3ec5

10 files changed

Lines changed: 244 additions & 531 deletions
Lines changed: 40 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1+
import { GetGrafanaCommand } from '@clevercloud/client/cc-api-commands/grafana/get-grafana-command.js';
12
import { get as getAddon } from '@clevercloud/client/esm/api/v2/addon.js';
2-
import { getGrafanaOrganisation } from '@clevercloud/client/esm/api/v4/saas.js';
33
import { ONE_SECOND } from '@clevercloud/client/esm/with-cache.js';
44
import { getDevHubUrl } from '../../lib/dev-hub-url.js';
55
import { sendToApi } from '../../lib/send-to-api.js';
66

77
/**
8+
* @import { CcApiClient } from '@clevercloud/client/cc-api-client.js'
89
* @import { AddonInfoStateLoaded, RawAddon } from './cc-addon-info.types.js'
9-
* @import { OperatorVersionInfo, RawOperator } from '../../operators.types.js'
10+
* @import { CheckKeycloakVersionCommandOutput } from '@clevercloud/client/cc-api-commands/keycloak/check-keycloak-version-command.types.js'
11+
* @import { CheckOtoroshiVersionCommandOutput } from '@clevercloud/client/cc-api-commands/otoroshi/check-otoroshi-version-command.types.js'
12+
* @import { CheckMetabaseVersionCommandOutput } from '@clevercloud/client/cc-api-commands/metabase/check-metabase-version-command.types.js'
1013
* @import { ApiConfig } from '../../lib/send-to-api.types.js'
1114
*/
1215

@@ -16,17 +19,12 @@ export class CcAddonInfoClient {
1619
* @param {ApiConfig} config.apiConfig - API configuration
1720
* @param {string} config.ownerId - Owner identifier
1821
* @param {string} config.addonId - Addon identifier
19-
* @param {string} config.providerId
20-
* @param {{ base: string, console: string }} [config.grafanaLink] - Base url to build a grafana link to the app
2122
* @param {AbortSignal} config.signal - Signal to abort calls
2223
*/
23-
constructor({ apiConfig, ownerId, addonId, providerId, grafanaLink, signal }) {
24+
constructor({ apiConfig, ownerId, addonId, signal }) {
2425
this._apiConfig = apiConfig;
2526
this._ownerId = ownerId;
2627
this._addonId = addonId;
27-
this.providerId = providerId;
28-
this._grafanaLink = grafanaLink;
29-
this._realId = null;
3028
this._signal = signal;
3129
}
3230

@@ -36,133 +34,10 @@ export class CcAddonInfoClient {
3634
sendToApi({ apiConfig: this._apiConfig, signal: this._signal, cacheDelay: ONE_SECOND }),
3735
);
3836
}
39-
40-
/**
41-
* @param {string} providerId
42-
* @param {string} realId
43-
* @returns {Promise<RawOperator>}
44-
*/
45-
_getOperator(providerId, realId) {
46-
return getOperator({ providerId, realId }).then(
47-
sendToApi({ apiConfig: this._apiConfig, signal: this._signal, cacheDelay: ONE_SECOND }),
48-
);
49-
}
50-
51-
/** @returns {Promise<OperatorVersionInfo>} */
52-
getOperatorVersionInfo() {
53-
return checkOperatorVersion({ providerId: this.providerId, realId: this._realId }).then(
54-
sendToApi({ apiConfig: this._apiConfig, signal: this._signal }),
55-
);
56-
}
57-
58-
/**
59-
* @param {Object} parameters
60-
* @param {string} parameters.resourceId
61-
* @param {AbortSignal} parameters.signal
62-
* @returns {Promise<string>}
63-
*/
64-
_getGrafanaAppLink({ resourceId, signal }) {
65-
return getGrafanaOrganisation({ id: this._ownerId })
66-
.then(sendToApi({ apiConfig: this._apiConfig, signal }))
67-
.then(
68-
/** @param {{id: string}} grafanaOrg*/
69-
(grafanaOrg) => {
70-
const grafanaLink = new URL('/d/runtime/application-runtime', this._grafanaLink.base);
71-
grafanaLink.searchParams.set('orgId', grafanaOrg.id);
72-
grafanaLink.searchParams.set('var-SELECT_APP', resourceId);
73-
return grafanaLink.toString();
74-
},
75-
)
76-
.catch(
77-
/** @param {Error & { response?: { status?: number }}} error */
78-
(error) => {
79-
if (error.response?.status === 404) {
80-
return this._grafanaLink.console;
81-
}
82-
throw error;
83-
},
84-
);
85-
}
86-
87-
/**
88-
* @param {string} targetVersion
89-
* @returns {Promise<RawOperator>}
90-
**/
91-
updateOperatorVersion(targetVersion) {
92-
return updateOperatorVersion({ providerId: this.providerId, realId: this._realId }, { targetVersion }).then(
93-
sendToApi({ apiConfig: this._apiConfig }),
94-
);
95-
}
96-
97-
/**
98-
* @return {Promise<{addonInfo: RawAddon, operator: RawOperator, operatorVersionInfo: OperatorVersionInfo, grafanaAppLink: string}>}
99-
*/
100-
async getAddonInfo() {
101-
// Fetch addon to get realId,
102-
const rawAddon = await this._getAddon();
103-
this._realId = rawAddon.realId;
104-
this.providerId = /** @type {import('../common.types.js').RawAddonProvider} */ rawAddon.provider.id;
105-
// Fetch operator with realId,
106-
const [operator, operatorVersionInfo] = await Promise.all([
107-
this._getOperator(this.providerId, this._realId),
108-
this.getOperatorVersionInfo(),
109-
]);
110-
const grafanaAppLink =
111-
this._grafanaLink != null
112-
? await this._getGrafanaAppLink({ resourceId: operator.resources.entrypoint, signal: this._signal })
113-
: null;
114-
115-
return { addonInfo: rawAddon, operator, operatorVersionInfo, grafanaAppLink };
116-
}
11737
}
11838

11939
/**
120-
* @param {{ providerId: string, realId: string }} params
121-
*/
122-
function getOperator(params) {
123-
// no multipath for /self or /organisations/{id}
124-
return Promise.resolve({
125-
method: 'get',
126-
url: `/v4/addon-providers/addon-${params.providerId}/addons/${params.realId}`,
127-
headers: { Accept: 'application/json' },
128-
// no queryParams
129-
// no body
130-
});
131-
}
132-
133-
/**
134-
* @param {{ providerId: string, realId: string }} params
135-
*/
136-
function checkOperatorVersion(params) {
137-
// no multipath for /self or /organisations/{id}
138-
return Promise.resolve({
139-
method: 'get',
140-
url: `/v4/addon-providers/addon-${params.providerId}/addons/${params.realId}/version/check`,
141-
headers: { Accept: 'application/json' },
142-
// no queryParams
143-
// no body
144-
});
145-
}
146-
147-
/**
148-
* @param {object} params
149-
* @param {string} params.providerId
150-
* @param {string} params.realId
151-
* @param {object} body
152-
*/
153-
export function updateOperatorVersion(params, body) {
154-
// no multipath for /self or /organisations/{id}
155-
return Promise.resolve({
156-
method: 'post',
157-
url: `/v4/addon-providers/addon-${params.providerId}/addons/${params.realId}/version/update`,
158-
headers: { Accept: 'application/json', 'Content-Type': 'application/json' },
159-
// no queryParams
160-
body,
161-
});
162-
}
163-
164-
/**
165-
* @param {OperatorVersionInfo} operatorVersionInfo
40+
* @param {CheckKeycloakVersionCommandOutput | CheckOtoroshiVersionCommandOutput | CheckMetabaseVersionCommandOutput} operatorVersionInfo
16641
* @returns {AddonInfoStateLoaded['version']}
16742
**/
16843
export function formatVersionState(operatorVersionInfo) {
@@ -182,3 +57,36 @@ export function formatVersionState(operatorVersionInfo) {
18257
latest: operatorVersionInfo.latest,
18358
};
18459
}
60+
61+
/**
62+
* Resolves the Grafana app link for an addon.
63+
*
64+
* - If `grafanaLink` is `null` (Grafana disabled in the console), returns `null`.
65+
* - If the Grafana org exists, builds a dashboard URL with the given `dashboardPath` and `appId`.
66+
* - If the Grafana org does not exist, falls back to `grafanaLink.console`.
67+
*
68+
* @param {object} params
69+
* @param {{ base: string, console: string } | null} params.grafanaLink
70+
* @param {string} params.ownerId
71+
* @param {string} params.dashboardPath - Grafana dashboard path (e.g. '/d/runtime/application-runtime')
72+
* @param {string} params.appId - Value for the `var-SELECT_APP` query parameter
73+
* @param {CcApiClient} params.ccApiClient
74+
* @param {AbortSignal} params.signal
75+
* @returns {Promise<string | null>}
76+
*/
77+
export async function getGrafanaAppLink({ grafanaLink, ownerId, dashboardPath, appId, ccApiClient, signal }) {
78+
if (grafanaLink == null) {
79+
return null;
80+
}
81+
82+
const grafanaOrg = await ccApiClient.send(new GetGrafanaCommand({ ownerId }), { signal });
83+
84+
if (grafanaOrg != null) {
85+
const url = new URL(dashboardPath, grafanaLink.base);
86+
url.searchParams.set('orgId', String(grafanaOrg.id));
87+
url.searchParams.set('var-SELECT_APP', appId);
88+
return url.toString();
89+
}
90+
91+
return grafanaLink.console;
92+
}

src/components/cc-addon-info/cc-addon-info.smart-cellar.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ import '../cc-smart-container/cc-smart-container.js';
77
import { CcAddonInfoClient } from './cc-addon-info.client.js';
88
import './cc-addon-info.js';
99

10-
const PROVIDER_ID = 'cellar-addon';
11-
1210
/**
1311
* @import { CcAddonInfo } from './cc-addon-info.js'
1412
* @import { AddonInfoStateLoading } from './cc-addon-info.types.js'
@@ -92,7 +90,7 @@ class Api extends CcAddonInfoClient {
9290
* @param {AbortSignal} config.signal - Signal to abort calls
9391
*/
9492
constructor({ apiConfig, ownerId, addonId, signal }) {
95-
super({ apiConfig, ownerId, addonId, providerId: PROVIDER_ID, signal });
93+
super({ apiConfig, ownerId, addonId, signal });
9694
}
9795

9896
/**

0 commit comments

Comments
 (0)