@backstage/plugin-kubernetes-backend 0.17.1 → 0.17.2-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/alpha/package.json +1 -1
- package/dist/alpha.cjs.js +5 -19
- package/dist/alpha.cjs.js.map +1 -1
- package/dist/index.cjs.js +96 -212
- package/dist/index.cjs.js.map +1 -1
- package/package.json +12 -12
package/dist/index.cjs.js
CHANGED
|
@@ -78,24 +78,17 @@ class AnonymousStrategy {
|
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
var __defProp$c = Object.defineProperty;
|
|
82
|
-
var __defNormalProp$c = (obj, key, value) => key in obj ? __defProp$c(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
83
|
-
var __publicField$c = (obj, key, value) => {
|
|
84
|
-
__defNormalProp$c(obj, key + "" , value);
|
|
85
|
-
return value;
|
|
86
|
-
};
|
|
87
81
|
const defaultRegion = "us-east-1";
|
|
88
82
|
class AwsIamStrategy {
|
|
83
|
+
credsManager;
|
|
89
84
|
constructor(opts) {
|
|
90
|
-
__publicField$c(this, "credsManager");
|
|
91
85
|
this.credsManager = integrationAwsNode.DefaultAwsCredentialsManager.fromConfig(opts.config);
|
|
92
86
|
}
|
|
93
87
|
async getCredential(clusterDetails) {
|
|
94
|
-
var _a;
|
|
95
88
|
return {
|
|
96
89
|
type: "bearer token",
|
|
97
90
|
token: await this.getBearerToken(
|
|
98
|
-
|
|
91
|
+
clusterDetails.authMetadata[pluginKubernetesCommon.ANNOTATION_KUBERNETES_AWS_CLUSTER_ID] ?? clusterDetails.name,
|
|
99
92
|
clusterDetails.authMetadata[pluginKubernetesCommon.ANNOTATION_KUBERNETES_AWS_ASSUME_ROLE],
|
|
100
93
|
clusterDetails.authMetadata[pluginKubernetesCommon.ANNOTATION_KUBERNETES_AWS_EXTERNAL_ID]
|
|
101
94
|
)
|
|
@@ -105,8 +98,7 @@ class AwsIamStrategy {
|
|
|
105
98
|
return [];
|
|
106
99
|
}
|
|
107
100
|
async getBearerToken(clusterId, assumeRole, externalId) {
|
|
108
|
-
|
|
109
|
-
const region = (_a = process.env.AWS_REGION) != null ? _a : defaultRegion;
|
|
101
|
+
const region = process.env.AWS_REGION ?? defaultRegion;
|
|
110
102
|
let credentials = (await this.credsManager.getCredentialProvider()).sdkCredentialProvider;
|
|
111
103
|
if (assumeRole) {
|
|
112
104
|
credentials = credentialProviders.fromTemporaryCredentials({
|
|
@@ -143,13 +135,10 @@ class AwsIamStrategy {
|
|
|
143
135
|
},
|
|
144
136
|
{ expiresIn: 0 }
|
|
145
137
|
);
|
|
146
|
-
const query = Object.keys(
|
|
147
|
-
(q) => {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
(_a2 = request.query) == null ? void 0 : _a2[q]
|
|
151
|
-
)}`;
|
|
152
|
-
}
|
|
138
|
+
const query = Object.keys(request?.query ?? {}).map(
|
|
139
|
+
(q) => `${encodeURIComponent(q)}=${encodeURIComponent(
|
|
140
|
+
request.query?.[q]
|
|
141
|
+
)}`
|
|
153
142
|
).join("&");
|
|
154
143
|
const url = `https://${request.hostname}${request.path}?${query}`;
|
|
155
144
|
return `k8s-aws-v1.${Buffer.from(url).toString("base64url")}`;
|
|
@@ -159,20 +148,14 @@ class AwsIamStrategy {
|
|
|
159
148
|
}
|
|
160
149
|
}
|
|
161
150
|
|
|
162
|
-
var __defProp$b = Object.defineProperty;
|
|
163
|
-
var __defNormalProp$b = (obj, key, value) => key in obj ? __defProp$b(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
164
|
-
var __publicField$b = (obj, key, value) => {
|
|
165
|
-
__defNormalProp$b(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
166
|
-
return value;
|
|
167
|
-
};
|
|
168
151
|
const aksScope = "6dae42f8-4368-4678-94ff-3960e28e3630/.default";
|
|
169
152
|
class AzureIdentityStrategy {
|
|
170
153
|
constructor(logger, tokenCredential = new identity.DefaultAzureCredential()) {
|
|
171
154
|
this.logger = logger;
|
|
172
155
|
this.tokenCredential = tokenCredential;
|
|
173
|
-
__publicField$b(this, "accessToken", { token: "", expiresOnTimestamp: 0 });
|
|
174
|
-
__publicField$b(this, "newTokenPromise");
|
|
175
156
|
}
|
|
157
|
+
accessToken = { token: "", expiresOnTimestamp: 0 };
|
|
158
|
+
newTokenPromise;
|
|
176
159
|
async getCredential() {
|
|
177
160
|
if (!this.tokenRequiresRefresh()) {
|
|
178
161
|
return { type: "bearer token", token: this.accessToken.token };
|
|
@@ -254,15 +237,9 @@ class GoogleServiceAccountStrategy {
|
|
|
254
237
|
}
|
|
255
238
|
}
|
|
256
239
|
|
|
257
|
-
var __defProp$a = Object.defineProperty;
|
|
258
|
-
var __defNormalProp$a = (obj, key, value) => key in obj ? __defProp$a(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
259
|
-
var __publicField$a = (obj, key, value) => {
|
|
260
|
-
__defNormalProp$a(obj, key + "" , value);
|
|
261
|
-
return value;
|
|
262
|
-
};
|
|
263
240
|
class DispatchStrategy {
|
|
241
|
+
strategyMap;
|
|
264
242
|
constructor(options) {
|
|
265
|
-
__publicField$a(this, "strategyMap");
|
|
266
243
|
this.strategyMap = options.authStrategyMap;
|
|
267
244
|
}
|
|
268
245
|
getCredential(clusterDetails, auth) {
|
|
@@ -315,14 +292,13 @@ class ServiceAccountStrategy {
|
|
|
315
292
|
|
|
316
293
|
class OidcStrategy {
|
|
317
294
|
async getCredential(clusterDetails, authConfig) {
|
|
318
|
-
var _a;
|
|
319
295
|
const oidcTokenProvider = clusterDetails.authMetadata[pluginKubernetesCommon.ANNOTATION_KUBERNETES_OIDC_TOKEN_PROVIDER];
|
|
320
296
|
if (!oidcTokenProvider || oidcTokenProvider === "") {
|
|
321
297
|
throw new Error(
|
|
322
298
|
`oidc authProvider requires a configured oidcTokenProvider`
|
|
323
299
|
);
|
|
324
300
|
}
|
|
325
|
-
const token =
|
|
301
|
+
const token = authConfig.oidc?.[oidcTokenProvider];
|
|
326
302
|
if (!token) {
|
|
327
303
|
throw new Error(
|
|
328
304
|
`Auth token not found under oidc.${oidcTokenProvider} in request body`
|
|
@@ -342,29 +318,22 @@ class OidcStrategy {
|
|
|
342
318
|
}
|
|
343
319
|
}
|
|
344
320
|
|
|
345
|
-
var __defProp$9 = Object.defineProperty;
|
|
346
|
-
var __defNormalProp$9 = (obj, key, value) => key in obj ? __defProp$9(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
347
|
-
var __publicField$9 = (obj, key, value) => {
|
|
348
|
-
__defNormalProp$9(obj, key + "" , value);
|
|
349
|
-
return value;
|
|
350
|
-
};
|
|
351
321
|
class ConfigClusterLocator {
|
|
322
|
+
clusterDetails;
|
|
352
323
|
constructor(clusterDetails) {
|
|
353
|
-
__publicField$9(this, "clusterDetails");
|
|
354
324
|
this.clusterDetails = clusterDetails;
|
|
355
325
|
}
|
|
356
326
|
static fromConfig(config, authStrategy) {
|
|
357
327
|
const clusterNames = /* @__PURE__ */ new Set();
|
|
358
328
|
return new ConfigClusterLocator(
|
|
359
329
|
config.getConfigArray("clusters").map((c) => {
|
|
360
|
-
var _a, _b, _c;
|
|
361
330
|
const authMetadataBlock = c.getOptional("authMetadata");
|
|
362
331
|
const name = c.getString("name");
|
|
363
332
|
if (clusterNames.has(name)) {
|
|
364
333
|
throw new Error(`Duplicate cluster name '${name}'`);
|
|
365
334
|
}
|
|
366
335
|
clusterNames.add(name);
|
|
367
|
-
const authProvider =
|
|
336
|
+
const authProvider = authMetadataBlock?.[pluginKubernetesCommon.ANNOTATION_KUBERNETES_AUTH_PROVIDER] ?? c.getOptionalString("authProvider");
|
|
368
337
|
if (!authProvider) {
|
|
369
338
|
throw new Error(
|
|
370
339
|
`cluster '${name}' has no auth provider configured; this must be specified via the 'authProvider' or 'authMetadata.${pluginKubernetesCommon.ANNOTATION_KUBERNETES_AUTH_PROVIDER}' parameter`
|
|
@@ -375,8 +344,8 @@ class ConfigClusterLocator {
|
|
|
375
344
|
name,
|
|
376
345
|
...title && { title },
|
|
377
346
|
url: c.getString("url"),
|
|
378
|
-
skipTLSVerify:
|
|
379
|
-
skipMetricsLookup:
|
|
347
|
+
skipTLSVerify: c.getOptionalBoolean("skipTLSVerify") ?? false,
|
|
348
|
+
skipMetricsLookup: c.getOptionalBoolean("skipMetricsLookup") ?? false,
|
|
380
349
|
caData: c.getOptionalString("caData"),
|
|
381
350
|
caFile: c.getOptionalString("caFile"),
|
|
382
351
|
authMetadata: {
|
|
@@ -470,7 +439,7 @@ function runPeriodically(fn, delayMs) {
|
|
|
470
439
|
|
|
471
440
|
var name = "@backstage/plugin-kubernetes-backend";
|
|
472
441
|
var description = "A Backstage backend plugin that integrates towards Kubernetes";
|
|
473
|
-
var version = "0.17.
|
|
442
|
+
var version = "0.17.2-next.0";
|
|
474
443
|
var main = "src/index.ts";
|
|
475
444
|
var types = "src/index.ts";
|
|
476
445
|
var license = "Apache-2.0";
|
|
@@ -599,18 +568,17 @@ class GkeClusterLocator {
|
|
|
599
568
|
this.hasClusterDetails = hasClusterDetails;
|
|
600
569
|
}
|
|
601
570
|
static fromConfigWithClient(config, client, refreshInterval) {
|
|
602
|
-
|
|
603
|
-
const matchingResourceLabels = (_b = (_a = config.getOptionalConfigArray("matchingResourceLabels")) == null ? void 0 : _a.map((mrl) => {
|
|
571
|
+
const matchingResourceLabels = config.getOptionalConfigArray("matchingResourceLabels")?.map((mrl) => {
|
|
604
572
|
return { key: mrl.getString("key"), value: mrl.getString("value") };
|
|
605
|
-
})
|
|
573
|
+
}) ?? [];
|
|
606
574
|
const storeAuthProviderString = config.getOptionalString("authProvider") === "googleServiceAccount" ? "googleServiceAccount" : "google";
|
|
607
575
|
const options = {
|
|
608
576
|
projectId: config.getString("projectId"),
|
|
609
577
|
authProvider: storeAuthProviderString,
|
|
610
|
-
region:
|
|
611
|
-
skipTLSVerify:
|
|
612
|
-
skipMetricsLookup:
|
|
613
|
-
exposeDashboard:
|
|
578
|
+
region: config.getOptionalString("region") ?? "-",
|
|
579
|
+
skipTLSVerify: config.getOptionalBoolean("skipTLSVerify") ?? false,
|
|
580
|
+
skipMetricsLookup: config.getOptionalBoolean("skipMetricsLookup") ?? false,
|
|
581
|
+
exposeDashboard: config.getOptionalBoolean("exposeDashboard") ?? false,
|
|
614
582
|
matchingResourceLabels
|
|
615
583
|
};
|
|
616
584
|
const gkeClusterLocator = new GkeClusterLocator(options, client);
|
|
@@ -634,15 +602,13 @@ class GkeClusterLocator {
|
|
|
634
602
|
);
|
|
635
603
|
}
|
|
636
604
|
async getClusters() {
|
|
637
|
-
var _a;
|
|
638
605
|
if (!this.hasClusterDetails) {
|
|
639
606
|
await this.refreshClusters();
|
|
640
607
|
}
|
|
641
|
-
return
|
|
608
|
+
return this.clusterDetails ?? [];
|
|
642
609
|
}
|
|
643
610
|
// TODO pass caData into the object
|
|
644
611
|
async refreshClusters() {
|
|
645
|
-
var _a;
|
|
646
612
|
const {
|
|
647
613
|
projectId,
|
|
648
614
|
region,
|
|
@@ -657,32 +623,29 @@ class GkeClusterLocator {
|
|
|
657
623
|
};
|
|
658
624
|
try {
|
|
659
625
|
const [response] = await this.client.listClusters(request);
|
|
660
|
-
this.clusterDetails = (
|
|
661
|
-
return matchingResourceLabels
|
|
626
|
+
this.clusterDetails = (response.clusters ?? []).filter((r) => {
|
|
627
|
+
return matchingResourceLabels?.every((mrl) => {
|
|
662
628
|
if (!r.resourceLabels) {
|
|
663
629
|
return false;
|
|
664
630
|
}
|
|
665
631
|
return r.resourceLabels[mrl.key] === mrl.value;
|
|
666
632
|
});
|
|
667
|
-
}).map((r) => {
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
} : {}
|
|
684
|
-
};
|
|
685
|
-
});
|
|
633
|
+
}).map((r) => ({
|
|
634
|
+
// TODO filter out clusters which don't have name or endpoint
|
|
635
|
+
name: r.name ?? "unknown",
|
|
636
|
+
url: `https://${r.endpoint ?? ""}`,
|
|
637
|
+
authMetadata: { [pluginKubernetesCommon.ANNOTATION_KUBERNETES_AUTH_PROVIDER]: authProvider },
|
|
638
|
+
skipTLSVerify,
|
|
639
|
+
skipMetricsLookup,
|
|
640
|
+
...exposeDashboard ? {
|
|
641
|
+
dashboardApp: "gke",
|
|
642
|
+
dashboardParameters: {
|
|
643
|
+
projectId,
|
|
644
|
+
region,
|
|
645
|
+
clusterName: r.name
|
|
646
|
+
}
|
|
647
|
+
} : {}
|
|
648
|
+
}));
|
|
686
649
|
this.hasClusterDetails = true;
|
|
687
650
|
} catch (e) {
|
|
688
651
|
throw new errors.ForwardedError(
|
|
@@ -693,19 +656,13 @@ class GkeClusterLocator {
|
|
|
693
656
|
}
|
|
694
657
|
}
|
|
695
658
|
|
|
696
|
-
var __defProp$8 = Object.defineProperty;
|
|
697
|
-
var __defNormalProp$8 = (obj, key, value) => key in obj ? __defProp$8(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
698
|
-
var __publicField$8 = (obj, key, value) => {
|
|
699
|
-
__defNormalProp$8(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
700
|
-
return value;
|
|
701
|
-
};
|
|
702
659
|
function isObject(obj) {
|
|
703
660
|
return typeof obj === "object" && obj !== null && !Array.isArray(obj);
|
|
704
661
|
}
|
|
705
662
|
class CatalogClusterLocator {
|
|
663
|
+
catalogClient;
|
|
664
|
+
auth;
|
|
706
665
|
constructor(catalogClient, auth) {
|
|
707
|
-
__publicField$8(this, "catalogClient");
|
|
708
|
-
__publicField$8(this, "auth");
|
|
709
666
|
this.catalogClient = catalogClient;
|
|
710
667
|
this.auth = auth;
|
|
711
668
|
}
|
|
@@ -727,7 +684,7 @@ class CatalogClusterLocator {
|
|
|
727
684
|
{
|
|
728
685
|
filter: [filter]
|
|
729
686
|
},
|
|
730
|
-
|
|
687
|
+
options?.credentials ? {
|
|
731
688
|
token: (await this.auth.getPluginRequestToken({
|
|
732
689
|
onBehalfOf: options.credentials,
|
|
733
690
|
targetPluginId: "catalog"
|
|
@@ -765,18 +722,12 @@ class CatalogClusterLocator {
|
|
|
765
722
|
}
|
|
766
723
|
}
|
|
767
724
|
|
|
768
|
-
var __defProp$7 = Object.defineProperty;
|
|
769
|
-
var __defNormalProp$7 = (obj, key, value) => key in obj ? __defProp$7(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
770
|
-
var __publicField$7 = (obj, key, value) => {
|
|
771
|
-
__defNormalProp$7(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
772
|
-
return value;
|
|
773
|
-
};
|
|
774
725
|
class LocalKubectlProxyClusterLocator {
|
|
726
|
+
clusterDetails;
|
|
727
|
+
// verbatim: when false, IPv4 addresses are placed before IPv6 addresses, ignoring the order from the DNS resolver
|
|
728
|
+
// By default kubectl proxy listens on 127.0.0.1 instead of [::1]
|
|
729
|
+
lookupPromise = dns__default.default.promises.lookup("localhost", { verbatim: false });
|
|
775
730
|
constructor() {
|
|
776
|
-
__publicField$7(this, "clusterDetails");
|
|
777
|
-
// verbatim: when false, IPv4 addresses are placed before IPv6 addresses, ignoring the order from the DNS resolver
|
|
778
|
-
// By default kubectl proxy listens on 127.0.0.1 instead of [::1]
|
|
779
|
-
__publicField$7(this, "lookupPromise", dns__default.default.promises.lookup("localhost", { verbatim: false }));
|
|
780
731
|
this.clusterDetails = [
|
|
781
732
|
{
|
|
782
733
|
name: "local",
|
|
@@ -911,15 +862,9 @@ const addResourceRoutesToRouter = (router, catalogApi, objectsProvider, auth, ht
|
|
|
911
862
|
});
|
|
912
863
|
};
|
|
913
864
|
|
|
914
|
-
var __defProp$6 = Object.defineProperty;
|
|
915
|
-
var __defNormalProp$6 = (obj, key, value) => key in obj ? __defProp$6(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
916
|
-
var __publicField$6 = (obj, key, value) => {
|
|
917
|
-
__defNormalProp$6(obj, key + "" , value);
|
|
918
|
-
return value;
|
|
919
|
-
};
|
|
920
865
|
class CatalogRelationServiceLocator {
|
|
866
|
+
clusterSupplier;
|
|
921
867
|
constructor(clusterSupplier) {
|
|
922
|
-
__publicField$6(this, "clusterSupplier");
|
|
923
868
|
this.clusterSupplier = clusterSupplier;
|
|
924
869
|
}
|
|
925
870
|
// As this implementation always returns all clusters serviceId is ignored here
|
|
@@ -939,23 +884,14 @@ class CatalogRelationServiceLocator {
|
|
|
939
884
|
}
|
|
940
885
|
doesEntityDependOnCluster(entity, cluster) {
|
|
941
886
|
return entity.relations.some(
|
|
942
|
-
(rel) => {
|
|
943
|
-
var _a;
|
|
944
|
-
return rel.type === "dependsOn" && rel.targetRef === `resource:${(_a = entity.metadata.namespace) != null ? _a : "default"}/${cluster.name}`;
|
|
945
|
-
}
|
|
887
|
+
(rel) => rel.type === "dependsOn" && rel.targetRef === `resource:${entity.metadata.namespace ?? "default"}/${cluster.name}`
|
|
946
888
|
);
|
|
947
889
|
}
|
|
948
890
|
}
|
|
949
891
|
|
|
950
|
-
var __defProp$5 = Object.defineProperty;
|
|
951
|
-
var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
952
|
-
var __publicField$5 = (obj, key, value) => {
|
|
953
|
-
__defNormalProp$5(obj, key + "" , value);
|
|
954
|
-
return value;
|
|
955
|
-
};
|
|
956
892
|
class MultiTenantServiceLocator {
|
|
893
|
+
clusterSupplier;
|
|
957
894
|
constructor(clusterSupplier) {
|
|
958
|
-
__publicField$5(this, "clusterSupplier");
|
|
959
895
|
this.clusterSupplier = clusterSupplier;
|
|
960
896
|
}
|
|
961
897
|
// As this implementation always returns all clusters serviceId is ignored here
|
|
@@ -964,28 +900,18 @@ class MultiTenantServiceLocator {
|
|
|
964
900
|
}
|
|
965
901
|
}
|
|
966
902
|
|
|
967
|
-
var __defProp$4 = Object.defineProperty;
|
|
968
|
-
var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
969
|
-
var __publicField$4 = (obj, key, value) => {
|
|
970
|
-
__defNormalProp$4(obj, key + "" , value);
|
|
971
|
-
return value;
|
|
972
|
-
};
|
|
973
903
|
class SingleTenantServiceLocator {
|
|
904
|
+
clusterSupplier;
|
|
974
905
|
constructor(clusterSupplier) {
|
|
975
|
-
__publicField$4(this, "clusterSupplier");
|
|
976
906
|
this.clusterSupplier = clusterSupplier;
|
|
977
907
|
}
|
|
978
908
|
// As this implementation always returns all clusters serviceId is ignored here
|
|
979
909
|
getClustersByEntity(_entity, requestContext) {
|
|
980
910
|
return this.clusterSupplier.getClusters({ credentials: requestContext.credentials }).then((clusters) => {
|
|
981
|
-
|
|
982
|
-
if ((_b = (_a = _entity.metadata) == null ? void 0 : _a.annotations) == null ? void 0 : _b["backstage.io/kubernetes-cluster"]) {
|
|
911
|
+
if (_entity.metadata?.annotations?.["backstage.io/kubernetes-cluster"]) {
|
|
983
912
|
return {
|
|
984
913
|
clusters: clusters.filter(
|
|
985
|
-
(c) =>
|
|
986
|
-
var _a2, _b2;
|
|
987
|
-
return c.name === ((_b2 = (_a2 = _entity.metadata) == null ? void 0 : _a2.annotations) == null ? void 0 : _b2["backstage.io/kubernetes-cluster"]);
|
|
988
|
-
}
|
|
914
|
+
(c) => c.name === _entity.metadata?.annotations?.["backstage.io/kubernetes-cluster"]
|
|
989
915
|
)
|
|
990
916
|
};
|
|
991
917
|
}
|
|
@@ -994,12 +920,6 @@ class SingleTenantServiceLocator {
|
|
|
994
920
|
}
|
|
995
921
|
}
|
|
996
922
|
|
|
997
|
-
var __defProp$3 = Object.defineProperty;
|
|
998
|
-
var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
999
|
-
var __publicField$3 = (obj, key, value) => {
|
|
1000
|
-
__defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
1001
|
-
return value;
|
|
1002
|
-
};
|
|
1003
923
|
const DEFAULT_OBJECTS = [
|
|
1004
924
|
{
|
|
1005
925
|
group: "",
|
|
@@ -1110,6 +1030,12 @@ const toClientSafePodMetrics = (podMetrics) => {
|
|
|
1110
1030
|
});
|
|
1111
1031
|
};
|
|
1112
1032
|
class KubernetesFanOutHandler {
|
|
1033
|
+
logger;
|
|
1034
|
+
fetcher;
|
|
1035
|
+
serviceLocator;
|
|
1036
|
+
customResources;
|
|
1037
|
+
objectTypesToFetch;
|
|
1038
|
+
authStrategy;
|
|
1113
1039
|
constructor({
|
|
1114
1040
|
logger,
|
|
1115
1041
|
fetcher,
|
|
@@ -1118,12 +1044,6 @@ class KubernetesFanOutHandler {
|
|
|
1118
1044
|
objectTypesToFetch = DEFAULT_OBJECTS,
|
|
1119
1045
|
authStrategy
|
|
1120
1046
|
}) {
|
|
1121
|
-
__publicField$3(this, "logger");
|
|
1122
|
-
__publicField$3(this, "fetcher");
|
|
1123
|
-
__publicField$3(this, "serviceLocator");
|
|
1124
|
-
__publicField$3(this, "customResources");
|
|
1125
|
-
__publicField$3(this, "objectTypesToFetch");
|
|
1126
|
-
__publicField$3(this, "authStrategy");
|
|
1127
1047
|
this.logger = logger;
|
|
1128
1048
|
this.fetcher = fetcher;
|
|
1129
1049
|
this.serviceLocator = serviceLocator;
|
|
@@ -1151,18 +1071,17 @@ class KubernetesFanOutHandler {
|
|
|
1151
1071
|
);
|
|
1152
1072
|
}
|
|
1153
1073
|
async fanOutRequests(entity, auth, options, objectTypesToFetch, customResources) {
|
|
1154
|
-
|
|
1155
|
-
const entityName = ((_b = (_a = entity.metadata) == null ? void 0 : _a.annotations) == null ? void 0 : _b["backstage.io/kubernetes-id"]) || ((_c = entity.metadata) == null ? void 0 : _c.name);
|
|
1074
|
+
const entityName = entity.metadata?.annotations?.["backstage.io/kubernetes-id"] || entity.metadata?.name;
|
|
1156
1075
|
const { clusters } = await this.serviceLocator.getClustersByEntity(entity, {
|
|
1157
1076
|
objectTypesToFetch,
|
|
1158
|
-
customResources: customResources
|
|
1077
|
+
customResources: customResources ?? [],
|
|
1159
1078
|
credentials: options.credentials
|
|
1160
1079
|
});
|
|
1161
1080
|
this.logger.info(
|
|
1162
1081
|
`entity.metadata.name=${entityName} clusterDetails=[${clusters.map((c) => c.name).join(", ")}]`
|
|
1163
1082
|
);
|
|
1164
|
-
const labelSelector =
|
|
1165
|
-
const namespace =
|
|
1083
|
+
const labelSelector = entity.metadata?.annotations?.["backstage.io/kubernetes-label-selector"] || `backstage.io/kubernetes-id=${entityName}`;
|
|
1084
|
+
const namespace = entity.metadata?.annotations?.["backstage.io/kubernetes-namespace"];
|
|
1166
1085
|
return Promise.all(
|
|
1167
1086
|
clusters.map(async (clusterDetails) => {
|
|
1168
1087
|
const credential = await this.authStrategy.getCredential(
|
|
@@ -1204,10 +1123,7 @@ class KubernetesFanOutHandler {
|
|
|
1204
1123
|
toObjectsByEntityResponse(clusterObjects) {
|
|
1205
1124
|
return {
|
|
1206
1125
|
items: clusterObjects.filter(
|
|
1207
|
-
(item) => item.errors !== void 0 && item.errors.length >= 1 || item.resources !== void 0 && item.resources.length >= 1 && item.resources.some((fr) =>
|
|
1208
|
-
var _a;
|
|
1209
|
-
return ((_a = fr.resources) == null ? void 0 : _a.length) >= 1;
|
|
1210
|
-
})
|
|
1126
|
+
(item) => item.errors !== void 0 && item.errors.length >= 1 || item.resources !== void 0 && item.resources.length >= 1 && item.resources.some((fr) => fr.resources?.length >= 1)
|
|
1211
1127
|
)
|
|
1212
1128
|
};
|
|
1213
1129
|
}
|
|
@@ -1237,10 +1153,7 @@ class KubernetesFanOutHandler {
|
|
|
1237
1153
|
return [result, []];
|
|
1238
1154
|
}
|
|
1239
1155
|
const namespaces = new Set(
|
|
1240
|
-
result.responses.filter(isPodFetchResponse).flatMap((r) => r.resources).map((p) =>
|
|
1241
|
-
var _a;
|
|
1242
|
-
return (_a = p.metadata) == null ? void 0 : _a.namespace;
|
|
1243
|
-
}).filter(isString)
|
|
1156
|
+
result.responses.filter(isPodFetchResponse).flatMap((r) => r.resources).map((p) => p.metadata?.namespace).filter(isString)
|
|
1244
1157
|
);
|
|
1245
1158
|
if (namespaces.size === 0) {
|
|
1246
1159
|
return [result, []];
|
|
@@ -1256,21 +1169,14 @@ class KubernetesFanOutHandler {
|
|
|
1256
1169
|
}
|
|
1257
1170
|
}
|
|
1258
1171
|
|
|
1259
|
-
var __defProp$2 = Object.defineProperty;
|
|
1260
|
-
var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
1261
|
-
var __publicField$2 = (obj, key, value) => {
|
|
1262
|
-
__defNormalProp$2(obj, key + "" , value);
|
|
1263
|
-
return value;
|
|
1264
|
-
};
|
|
1265
1172
|
const isError = (fr) => fr.hasOwnProperty("errorType");
|
|
1266
1173
|
function fetchResultsToResponseWrapper(results) {
|
|
1267
|
-
var _a, _b;
|
|
1268
1174
|
const groupBy = lodash__default.default.groupBy(results, (value) => {
|
|
1269
1175
|
return isError(value) ? "errors" : "responses";
|
|
1270
1176
|
});
|
|
1271
1177
|
return {
|
|
1272
|
-
errors:
|
|
1273
|
-
responses:
|
|
1178
|
+
errors: groupBy.errors ?? [],
|
|
1179
|
+
responses: groupBy.responses ?? []
|
|
1274
1180
|
};
|
|
1275
1181
|
}
|
|
1276
1182
|
const statusCodeToErrorType = (statusCode) => {
|
|
@@ -1288,8 +1194,8 @@ const statusCodeToErrorType = (statusCode) => {
|
|
|
1288
1194
|
}
|
|
1289
1195
|
};
|
|
1290
1196
|
class KubernetesClientBasedFetcher {
|
|
1197
|
+
logger;
|
|
1291
1198
|
constructor({ logger }) {
|
|
1292
|
-
__publicField$2(this, "logger");
|
|
1293
1199
|
this.logger = logger;
|
|
1294
1200
|
}
|
|
1295
1201
|
fetchObjectsForService(params) {
|
|
@@ -1408,7 +1314,6 @@ class KubernetesClientBasedFetcher {
|
|
|
1408
1314
|
return authProvider !== "localKubectlProxy" && credential.type === "anonymous";
|
|
1409
1315
|
}
|
|
1410
1316
|
fetchArgs(clusterDetails, credential) {
|
|
1411
|
-
var _a;
|
|
1412
1317
|
const requestInit = {
|
|
1413
1318
|
method: "GET",
|
|
1414
1319
|
headers: {
|
|
@@ -1422,10 +1327,10 @@ class KubernetesClientBasedFetcher {
|
|
|
1422
1327
|
const url = new URL(clusterDetails.url);
|
|
1423
1328
|
if (url.protocol === "https:") {
|
|
1424
1329
|
requestInit.agent = new https__namespace.Agent({
|
|
1425
|
-
ca:
|
|
1330
|
+
ca: clientNode.bufferFromFileOrString(
|
|
1426
1331
|
clusterDetails.caFile,
|
|
1427
1332
|
clusterDetails.caData
|
|
1428
|
-
)
|
|
1333
|
+
) ?? void 0,
|
|
1429
1334
|
rejectUnauthorized: !clusterDetails.skipTLSVerify,
|
|
1430
1335
|
...credential.type === "x509 client certificate" && {
|
|
1431
1336
|
cert: credential.cert,
|
|
@@ -1459,21 +1364,15 @@ class KubernetesClientBasedFetcher {
|
|
|
1459
1364
|
}
|
|
1460
1365
|
}
|
|
1461
1366
|
|
|
1462
|
-
var __defProp$1 = Object.defineProperty;
|
|
1463
|
-
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
1464
|
-
var __publicField$1 = (obj, key, value) => {
|
|
1465
|
-
__defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
1466
|
-
return value;
|
|
1467
|
-
};
|
|
1468
1367
|
const HEADER_KUBERNETES_CLUSTER = "Backstage-Kubernetes-Cluster";
|
|
1469
1368
|
const HEADER_KUBERNETES_AUTH = "Backstage-Kubernetes-Authorization";
|
|
1470
1369
|
class KubernetesProxy {
|
|
1370
|
+
middlewareForClusterName = /* @__PURE__ */ new Map();
|
|
1371
|
+
logger;
|
|
1372
|
+
clusterSupplier;
|
|
1373
|
+
authStrategy;
|
|
1374
|
+
httpAuth;
|
|
1471
1375
|
constructor(options) {
|
|
1472
|
-
__publicField$1(this, "middlewareForClusterName", /* @__PURE__ */ new Map());
|
|
1473
|
-
__publicField$1(this, "logger");
|
|
1474
|
-
__publicField$1(this, "clusterSupplier");
|
|
1475
|
-
__publicField$1(this, "authStrategy");
|
|
1476
|
-
__publicField$1(this, "httpAuth");
|
|
1477
1376
|
this.logger = options.logger;
|
|
1478
1377
|
this.clusterSupplier = options.clusterSupplier;
|
|
1479
1378
|
this.authStrategy = options.authStrategy;
|
|
@@ -1486,7 +1385,6 @@ class KubernetesProxy {
|
|
|
1486
1385
|
createRequestHandler(options) {
|
|
1487
1386
|
const { permissionApi } = options;
|
|
1488
1387
|
return async (req, res, next) => {
|
|
1489
|
-
var _a, _b;
|
|
1490
1388
|
const authorizeResponse = await permissionApi.authorize(
|
|
1491
1389
|
[{ permission: pluginKubernetesCommon.kubernetesProxyPermission }],
|
|
1492
1390
|
{
|
|
@@ -1499,7 +1397,7 @@ class KubernetesProxy {
|
|
|
1499
1397
|
return;
|
|
1500
1398
|
}
|
|
1501
1399
|
const middleware = await this.getMiddleware(req);
|
|
1502
|
-
if (
|
|
1400
|
+
if (req.header("connection")?.toLowerCase() === "upgrade" && req.header("upgrade")?.toLowerCase() === "websocket") {
|
|
1503
1401
|
middleware.upgrade(req, req.socket, void 0);
|
|
1504
1402
|
} else {
|
|
1505
1403
|
middleware(req, res, next);
|
|
@@ -1529,17 +1427,16 @@ class KubernetesProxy {
|
|
|
1529
1427
|
);
|
|
1530
1428
|
},
|
|
1531
1429
|
router: async (req) => {
|
|
1532
|
-
var _a;
|
|
1533
1430
|
const cluster = await this.getClusterForRequest(req);
|
|
1534
1431
|
const url = new URL(cluster.url);
|
|
1535
1432
|
const target = {
|
|
1536
1433
|
protocol: url.protocol,
|
|
1537
1434
|
host: url.hostname,
|
|
1538
1435
|
port: url.port,
|
|
1539
|
-
ca:
|
|
1436
|
+
ca: clientNode.bufferFromFileOrString(
|
|
1540
1437
|
cluster.caFile,
|
|
1541
1438
|
cluster.caData
|
|
1542
|
-
)
|
|
1439
|
+
)?.toString()
|
|
1543
1440
|
};
|
|
1544
1441
|
const authHeader = req.headers[HEADER_KUBERNETES_AUTH.toLocaleLowerCase("en-US")];
|
|
1545
1442
|
if (typeof authHeader === "string") {
|
|
@@ -1644,25 +1541,19 @@ class KubernetesProxy {
|
|
|
1644
1541
|
}
|
|
1645
1542
|
}
|
|
1646
1543
|
|
|
1647
|
-
var __defProp = Object.defineProperty;
|
|
1648
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
1649
|
-
var __publicField = (obj, key, value) => {
|
|
1650
|
-
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
1651
|
-
return value;
|
|
1652
|
-
};
|
|
1653
1544
|
class KubernetesBuilder {
|
|
1654
1545
|
constructor(env) {
|
|
1655
1546
|
this.env = env;
|
|
1656
|
-
__publicField(this, "clusterSupplier");
|
|
1657
|
-
__publicField(this, "defaultClusterRefreshInterval", luxon.Duration.fromObject({
|
|
1658
|
-
minutes: 60
|
|
1659
|
-
}));
|
|
1660
|
-
__publicField(this, "objectsProvider");
|
|
1661
|
-
__publicField(this, "fetcher");
|
|
1662
|
-
__publicField(this, "serviceLocator");
|
|
1663
|
-
__publicField(this, "proxy");
|
|
1664
|
-
__publicField(this, "authStrategyMap");
|
|
1665
1547
|
}
|
|
1548
|
+
clusterSupplier;
|
|
1549
|
+
defaultClusterRefreshInterval = luxon.Duration.fromObject({
|
|
1550
|
+
minutes: 60
|
|
1551
|
+
});
|
|
1552
|
+
objectsProvider;
|
|
1553
|
+
fetcher;
|
|
1554
|
+
serviceLocator;
|
|
1555
|
+
proxy;
|
|
1556
|
+
authStrategyMap;
|
|
1666
1557
|
static createBuilder(env) {
|
|
1667
1558
|
return new KubernetesBuilder(env);
|
|
1668
1559
|
}
|
|
@@ -1761,8 +1652,7 @@ class KubernetesBuilder {
|
|
|
1761
1652
|
return this;
|
|
1762
1653
|
}
|
|
1763
1654
|
buildCustomResources() {
|
|
1764
|
-
|
|
1765
|
-
const customResources = ((_a = this.env.config.getOptionalConfigArray("kubernetes.customResources")) != null ? _a : []).map(
|
|
1655
|
+
const customResources = (this.env.config.getOptionalConfigArray("kubernetes.customResources") ?? []).map(
|
|
1766
1656
|
(c) => ({
|
|
1767
1657
|
group: c.getString("group"),
|
|
1768
1658
|
apiVersion: c.getString("apiVersion"),
|
|
@@ -1940,23 +1830,19 @@ class KubernetesBuilder {
|
|
|
1940
1830
|
);
|
|
1941
1831
|
}
|
|
1942
1832
|
getFetcher() {
|
|
1943
|
-
|
|
1944
|
-
return (_a = this.fetcher) != null ? _a : this.buildFetcher();
|
|
1833
|
+
return this.fetcher ?? this.buildFetcher();
|
|
1945
1834
|
}
|
|
1946
1835
|
getClusterSupplier() {
|
|
1947
|
-
|
|
1948
|
-
return (_a = this.clusterSupplier) != null ? _a : this.buildClusterSupplier(this.defaultClusterRefreshInterval);
|
|
1836
|
+
return this.clusterSupplier ?? this.buildClusterSupplier(this.defaultClusterRefreshInterval);
|
|
1949
1837
|
}
|
|
1950
1838
|
getServiceLocator() {
|
|
1951
|
-
|
|
1952
|
-
return (_a = this.serviceLocator) != null ? _a : this.buildServiceLocator(
|
|
1839
|
+
return this.serviceLocator ?? this.buildServiceLocator(
|
|
1953
1840
|
this.getServiceLocatorMethod(),
|
|
1954
1841
|
this.getClusterSupplier()
|
|
1955
1842
|
);
|
|
1956
1843
|
}
|
|
1957
1844
|
getObjectsProvider(options) {
|
|
1958
|
-
|
|
1959
|
-
return (_a = this.objectsProvider) != null ? _a : this.buildObjectsProvider(options);
|
|
1845
|
+
return this.objectsProvider ?? this.buildObjectsProvider(options);
|
|
1960
1846
|
}
|
|
1961
1847
|
getObjectTypesToFetch() {
|
|
1962
1848
|
const objectTypesToFetchStrings = this.env.config.getOptionalStringArray(
|
|
@@ -1972,7 +1858,7 @@ class KubernetesBuilder {
|
|
|
1972
1858
|
);
|
|
1973
1859
|
}
|
|
1974
1860
|
if (apiVersionOverrides) {
|
|
1975
|
-
objectTypesToFetch = objectTypesToFetch
|
|
1861
|
+
objectTypesToFetch = objectTypesToFetch ?? DEFAULT_OBJECTS;
|
|
1976
1862
|
for (const obj of objectTypesToFetch) {
|
|
1977
1863
|
if (apiVersionOverrides.has(obj.objectType)) {
|
|
1978
1864
|
obj.apiVersion = apiVersionOverrides.getString(obj.objectType);
|
|
@@ -1982,12 +1868,10 @@ class KubernetesBuilder {
|
|
|
1982
1868
|
return objectTypesToFetch;
|
|
1983
1869
|
}
|
|
1984
1870
|
getProxy(logger, clusterSupplier, discovery, httpAuth) {
|
|
1985
|
-
|
|
1986
|
-
return (_a = this.proxy) != null ? _a : this.buildProxy(logger, clusterSupplier, discovery, httpAuth);
|
|
1871
|
+
return this.proxy ?? this.buildProxy(logger, clusterSupplier, discovery, httpAuth);
|
|
1987
1872
|
}
|
|
1988
1873
|
getAuthStrategyMap() {
|
|
1989
|
-
|
|
1990
|
-
return (_a = this.authStrategyMap) != null ? _a : this.buildAuthStrategyMap();
|
|
1874
|
+
return this.authStrategyMap ?? this.buildAuthStrategyMap();
|
|
1991
1875
|
}
|
|
1992
1876
|
}
|
|
1993
1877
|
|