@kuadrant/kuadrant-backstage-plugin-backend 0.0.1-test.1-1593c3ec
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/README.md +28 -0
- package/alpha/module.cjs.js +31 -0
- package/alpha/package.json +11 -0
- package/dist/alpha.cjs.js +31 -0
- package/dist/alpha.cjs.js.map +1 -0
- package/dist/index.cjs.js +35 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/k8s-client.cjs.js +269 -0
- package/dist/k8s-client.cjs.js.map +1 -0
- package/dist/permissions-router.cjs.js +13 -0
- package/dist/permissions-router.cjs.js.map +1 -0
- package/dist/permissions.cjs.js +124 -0
- package/dist/permissions.cjs.js.map +1 -0
- package/dist/plugin.cjs.js +38 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/providers/APIProductEntityProvider.cjs.js +131 -0
- package/dist/providers/APIProductEntityProvider.cjs.js.map +1 -0
- package/dist/rbac.cjs.js +27 -0
- package/dist/rbac.cjs.js.map +1 -0
- package/dist/router.cjs.js +820 -0
- package/dist/router.cjs.js.map +1 -0
- package/package.json +78 -0
- package/rbac/index.ts +1 -0
- package/rbac/package.json +11 -0
package/README.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# kuadrant
|
|
2
|
+
|
|
3
|
+
This plugin backend was templated using the Backstage CLI. You should replace this text with a description of your plugin backend.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
This plugin is installed via the `@internal/plugin-kuadrant-backend` package. To install it to your backend package, run the following command:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# From your root directory
|
|
11
|
+
yarn --cwd packages/backend add @internal/plugin-kuadrant-backend
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Then add the plugin to your backend in `packages/backend/src/index.ts`:
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
const backend = createBackend();
|
|
18
|
+
// ...
|
|
19
|
+
backend.add(import('@internal/plugin-kuadrant-backend'));
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Development
|
|
23
|
+
|
|
24
|
+
This plugin backend can be started in a standalone mode from directly in this
|
|
25
|
+
package with `yarn start`. It is a limited setup that is most convenient when
|
|
26
|
+
developing the plugin backend itself.
|
|
27
|
+
|
|
28
|
+
If you want to run the entire project, including the frontend, run `yarn start` from the root directory.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var backendPluginApi = require('@backstage/backend-plugin-api');
|
|
6
|
+
var alpha = require('@backstage/plugin-catalog-node/alpha');
|
|
7
|
+
var APIProductEntityProvider = require('./providers/APIProductEntityProvider.cjs.js');
|
|
8
|
+
|
|
9
|
+
const catalogModuleApiProductEntityProvider = backendPluginApi.createBackendModule({
|
|
10
|
+
pluginId: "catalog",
|
|
11
|
+
moduleId: "kuadrant-apiproduct-provider",
|
|
12
|
+
register(env) {
|
|
13
|
+
env.registerInit({
|
|
14
|
+
deps: {
|
|
15
|
+
catalog: alpha.catalogProcessingExtensionPoint,
|
|
16
|
+
config: backendPluginApi.coreServices.rootConfig,
|
|
17
|
+
logger: backendPluginApi.coreServices.logger
|
|
18
|
+
},
|
|
19
|
+
async init({ catalog, config, logger }) {
|
|
20
|
+
logger.info("registering kuadrant apiproduct entity provider");
|
|
21
|
+
const provider = new APIProductEntityProvider.APIProductEntityProvider(config);
|
|
22
|
+
catalog.addEntityProvider(provider);
|
|
23
|
+
logger.info("apiproduct entity provider registered successfully");
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
exports.catalogModuleApiProductEntityProvider = catalogModuleApiProductEntityProvider;
|
|
30
|
+
exports.default = catalogModuleApiProductEntityProvider;
|
|
31
|
+
//# sourceMappingURL=module.cjs.js.map
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kuadrant/plugin-kuadrant-backend-alpha",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"main": "./module.cjs.js",
|
|
5
|
+
"types": "./module.d.ts",
|
|
6
|
+
"backstage": {
|
|
7
|
+
"role": "backend-plugin-module",
|
|
8
|
+
"pluginId": "catalog",
|
|
9
|
+
"pluginPackage": "@backstage/plugin-catalog-backend"
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var backendPluginApi = require('@backstage/backend-plugin-api');
|
|
6
|
+
var alpha = require('@backstage/plugin-catalog-node/alpha');
|
|
7
|
+
var APIProductEntityProvider = require('./providers/APIProductEntityProvider.cjs.js');
|
|
8
|
+
|
|
9
|
+
const catalogModuleApiProductEntityProvider = backendPluginApi.createBackendModule({
|
|
10
|
+
pluginId: "catalog",
|
|
11
|
+
moduleId: "kuadrant-apiproduct-provider",
|
|
12
|
+
register(env) {
|
|
13
|
+
env.registerInit({
|
|
14
|
+
deps: {
|
|
15
|
+
catalog: alpha.catalogProcessingExtensionPoint,
|
|
16
|
+
config: backendPluginApi.coreServices.rootConfig,
|
|
17
|
+
logger: backendPluginApi.coreServices.logger
|
|
18
|
+
},
|
|
19
|
+
async init({ catalog, config, logger }) {
|
|
20
|
+
logger.info("registering kuadrant apiproduct entity provider");
|
|
21
|
+
const provider = new APIProductEntityProvider.APIProductEntityProvider(config);
|
|
22
|
+
catalog.addEntityProvider(provider);
|
|
23
|
+
logger.info("apiproduct entity provider registered successfully");
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
exports.catalogModuleApiProductEntityProvider = catalogModuleApiProductEntityProvider;
|
|
30
|
+
exports.default = catalogModuleApiProductEntityProvider;
|
|
31
|
+
//# sourceMappingURL=alpha.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alpha.cjs.js","sources":["../src/module.ts"],"sourcesContent":["import {\n coreServices,\n createBackendModule,\n} from '@backstage/backend-plugin-api';\nimport { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha';\nimport { APIProductEntityProvider } from './providers/APIProductEntityProvider';\n\n/**\n * backend module for apiproduct entity provider\n * @public\n */\nexport const catalogModuleApiProductEntityProvider = createBackendModule({\n pluginId: 'catalog',\n moduleId: 'kuadrant-apiproduct-provider',\n register(env) {\n env.registerInit({\n deps: {\n catalog: catalogProcessingExtensionPoint,\n config: coreServices.rootConfig,\n logger: coreServices.logger,\n },\n async init({ catalog, config, logger }) {\n logger.info('registering kuadrant apiproduct entity provider');\n const provider = new APIProductEntityProvider(config);\n catalog.addEntityProvider(provider);\n logger.info('apiproduct entity provider registered successfully');\n },\n });\n },\n});\n\nexport default catalogModuleApiProductEntityProvider;\n\n"],"names":["createBackendModule","catalogProcessingExtensionPoint","coreServices","APIProductEntityProvider"],"mappings":";;;;;;;;AAWO,MAAM,wCAAwCA,oCAAoB,CAAA;AAAA,EACvE,QAAU,EAAA,SAAA;AAAA,EACV,QAAU,EAAA,8BAAA;AAAA,EACV,SAAS,GAAK,EAAA;AACZ,IAAA,GAAA,CAAI,YAAa,CAAA;AAAA,MACf,IAAM,EAAA;AAAA,QACJ,OAAS,EAAAC,qCAAA;AAAA,QACT,QAAQC,6BAAa,CAAA,UAAA;AAAA,QACrB,QAAQA,6BAAa,CAAA;AAAA,OACvB;AAAA,MACA,MAAM,IAAK,CAAA,EAAE,OAAS,EAAA,MAAA,EAAQ,QAAU,EAAA;AACtC,QAAA,MAAA,CAAO,KAAK,iDAAiD,CAAA;AAC7D,QAAM,MAAA,QAAA,GAAW,IAAIC,iDAAA,CAAyB,MAAM,CAAA;AACpD,QAAA,OAAA,CAAQ,kBAAkB,QAAQ,CAAA;AAClC,QAAA,MAAA,CAAO,KAAK,oDAAoD,CAAA;AAAA;AAClE,KACD,CAAA;AAAA;AAEL,CAAC;;;;;"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var plugin = require('./plugin.cjs.js');
|
|
6
|
+
var permissions = require('./permissions.cjs.js');
|
|
7
|
+
var alpha = require('./alpha.cjs.js');
|
|
8
|
+
var rbac = require('./rbac.cjs.js');
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
exports.default = plugin.kuadrantPlugin;
|
|
13
|
+
exports.kuadrantApiKeyDeleteAllPermission = permissions.kuadrantApiKeyDeleteAllPermission;
|
|
14
|
+
exports.kuadrantApiKeyDeleteOwnPermission = permissions.kuadrantApiKeyDeleteOwnPermission;
|
|
15
|
+
exports.kuadrantApiKeyReadAllPermission = permissions.kuadrantApiKeyReadAllPermission;
|
|
16
|
+
exports.kuadrantApiKeyReadOwnPermission = permissions.kuadrantApiKeyReadOwnPermission;
|
|
17
|
+
exports.kuadrantApiKeyRequestCreatePermission = permissions.kuadrantApiKeyRequestCreatePermission;
|
|
18
|
+
exports.kuadrantApiKeyRequestListPermission = permissions.kuadrantApiKeyRequestListPermission;
|
|
19
|
+
exports.kuadrantApiKeyRequestReadAllPermission = permissions.kuadrantApiKeyRequestReadAllPermission;
|
|
20
|
+
exports.kuadrantApiKeyRequestReadOwnPermission = permissions.kuadrantApiKeyRequestReadOwnPermission;
|
|
21
|
+
exports.kuadrantApiKeyRequestUpdatePermission = permissions.kuadrantApiKeyRequestUpdatePermission;
|
|
22
|
+
exports.kuadrantApiProductCreatePermission = permissions.kuadrantApiProductCreatePermission;
|
|
23
|
+
exports.kuadrantApiProductDeletePermission = permissions.kuadrantApiProductDeletePermission;
|
|
24
|
+
exports.kuadrantApiProductListPermission = permissions.kuadrantApiProductListPermission;
|
|
25
|
+
exports.kuadrantApiProductReadPermission = permissions.kuadrantApiProductReadPermission;
|
|
26
|
+
exports.kuadrantApiProductUpdatePermission = permissions.kuadrantApiProductUpdatePermission;
|
|
27
|
+
exports.kuadrantPermissions = permissions.kuadrantPermissions;
|
|
28
|
+
exports.kuadrantPlanPolicyCreatePermission = permissions.kuadrantPlanPolicyCreatePermission;
|
|
29
|
+
exports.kuadrantPlanPolicyDeletePermission = permissions.kuadrantPlanPolicyDeletePermission;
|
|
30
|
+
exports.kuadrantPlanPolicyListPermission = permissions.kuadrantPlanPolicyListPermission;
|
|
31
|
+
exports.kuadrantPlanPolicyReadPermission = permissions.kuadrantPlanPolicyReadPermission;
|
|
32
|
+
exports.kuadrantPlanPolicyUpdatePermission = permissions.kuadrantPlanPolicyUpdatePermission;
|
|
33
|
+
exports.catalogModuleApiProductEntityProvider = alpha.catalogModuleApiProductEntityProvider;
|
|
34
|
+
exports.kuadrantRbacModule = rbac.kuadrantRbacModule;
|
|
35
|
+
//# sourceMappingURL=index.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var k8s = require('@kubernetes/client-node');
|
|
4
|
+
|
|
5
|
+
function _interopNamespaceCompat(e) {
|
|
6
|
+
if (e && typeof e === 'object' && 'default' in e) return e;
|
|
7
|
+
var n = Object.create(null);
|
|
8
|
+
if (e) {
|
|
9
|
+
Object.keys(e).forEach(function (k) {
|
|
10
|
+
if (k !== 'default') {
|
|
11
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
12
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () { return e[k]; }
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
n.default = e;
|
|
20
|
+
return Object.freeze(n);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
var k8s__namespace = /*#__PURE__*/_interopNamespaceCompat(k8s);
|
|
24
|
+
|
|
25
|
+
class KuadrantK8sClient {
|
|
26
|
+
kc;
|
|
27
|
+
customApi;
|
|
28
|
+
coreApi;
|
|
29
|
+
constructor(config) {
|
|
30
|
+
this.kc = new k8s__namespace.KubeConfig();
|
|
31
|
+
const hasK8sConfig = config.has("kubernetes");
|
|
32
|
+
if (hasK8sConfig) {
|
|
33
|
+
const clusterLocatorMethods = config.getOptionalConfigArray("kubernetes.clusterLocatorMethods") || [];
|
|
34
|
+
const configLocator = clusterLocatorMethods.find((c) => c.getString("type") === "config");
|
|
35
|
+
if (configLocator) {
|
|
36
|
+
const clusters = configLocator.getOptionalConfigArray("clusters") || [];
|
|
37
|
+
if (clusters.length > 0) {
|
|
38
|
+
const clusterConfig = clusters[0];
|
|
39
|
+
const clusterName = clusterConfig.getString("name");
|
|
40
|
+
const clusterUrl = clusterConfig.getString("url");
|
|
41
|
+
const authProvider = clusterConfig.getOptionalString("authProvider");
|
|
42
|
+
const skipTLSVerify = clusterConfig.getOptionalBoolean("skipTLSVerify") || false;
|
|
43
|
+
if (authProvider === "serviceAccount") {
|
|
44
|
+
const serviceAccountToken = clusterConfig.getString("serviceAccountToken");
|
|
45
|
+
const cluster = {
|
|
46
|
+
name: clusterName,
|
|
47
|
+
server: clusterUrl,
|
|
48
|
+
skipTLSVerify
|
|
49
|
+
};
|
|
50
|
+
const user = {
|
|
51
|
+
name: `${clusterName}-service-account`,
|
|
52
|
+
token: serviceAccountToken
|
|
53
|
+
};
|
|
54
|
+
const context = {
|
|
55
|
+
name: `${clusterName}-context`,
|
|
56
|
+
cluster: clusterName,
|
|
57
|
+
user: user.name
|
|
58
|
+
};
|
|
59
|
+
this.kc.loadFromOptions({
|
|
60
|
+
clusters: [cluster],
|
|
61
|
+
users: [user],
|
|
62
|
+
contexts: [context],
|
|
63
|
+
currentContext: context.name
|
|
64
|
+
});
|
|
65
|
+
console.log(`k8s client initialised with explicit cluster config`);
|
|
66
|
+
console.log(` cluster: ${clusterName}`);
|
|
67
|
+
console.log(` url: ${clusterUrl}`);
|
|
68
|
+
console.log(` auth: serviceAccount`);
|
|
69
|
+
console.log(` skipTLSVerify: ${skipTLSVerify}`);
|
|
70
|
+
} else {
|
|
71
|
+
console.log(`unsupported authProvider: ${authProvider}, falling back to default`);
|
|
72
|
+
this.kc.loadFromDefault();
|
|
73
|
+
}
|
|
74
|
+
} else {
|
|
75
|
+
this.kc.loadFromDefault();
|
|
76
|
+
this.logDefaultConfig("no clusters defined");
|
|
77
|
+
}
|
|
78
|
+
} else {
|
|
79
|
+
this.kc.loadFromDefault();
|
|
80
|
+
this.logDefaultConfig("no config locator found");
|
|
81
|
+
}
|
|
82
|
+
} else {
|
|
83
|
+
this.kc.loadFromDefault();
|
|
84
|
+
this.logDefaultConfig("no kubernetes config in app-config.yaml");
|
|
85
|
+
}
|
|
86
|
+
this.customApi = this.kc.makeApiClient(k8s__namespace.CustomObjectsApi);
|
|
87
|
+
this.coreApi = this.kc.makeApiClient(k8s__namespace.CoreV1Api);
|
|
88
|
+
}
|
|
89
|
+
logDefaultConfig(reason) {
|
|
90
|
+
console.log(`k8s client initialised using default config (${reason})`);
|
|
91
|
+
const inClusterToken = process.env.KUBERNETES_SERVICE_HOST;
|
|
92
|
+
if (inClusterToken) {
|
|
93
|
+
console.log(" auth: in-cluster service account");
|
|
94
|
+
console.log(" location: /var/run/secrets/kubernetes.io/serviceaccount/");
|
|
95
|
+
} else {
|
|
96
|
+
const kubeconfig = process.env.KUBECONFIG || "~/.kube/config";
|
|
97
|
+
console.log(" auth: local kubeconfig");
|
|
98
|
+
console.log(` location: ${kubeconfig}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
async listCustomResources(group, version, plural, namespace) {
|
|
102
|
+
try {
|
|
103
|
+
const response = namespace ? await this.customApi.listNamespacedCustomObject(group, version, namespace, plural) : await this.customApi.listClusterCustomObject(group, version, plural);
|
|
104
|
+
return response.body;
|
|
105
|
+
} catch (error) {
|
|
106
|
+
throw new Error(`failed to list ${plural}: ${error.message}`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
async getCustomResource(group, version, namespace, plural, name) {
|
|
110
|
+
try {
|
|
111
|
+
const response = await this.customApi.getNamespacedCustomObject(
|
|
112
|
+
group,
|
|
113
|
+
version,
|
|
114
|
+
namespace,
|
|
115
|
+
plural,
|
|
116
|
+
name
|
|
117
|
+
);
|
|
118
|
+
return response.body;
|
|
119
|
+
} catch (error) {
|
|
120
|
+
throw new Error(`failed to get ${plural}/${name}: ${error.message}`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
async createSecret(namespace, secret) {
|
|
124
|
+
try {
|
|
125
|
+
const response = await this.coreApi.createNamespacedSecret(namespace, secret);
|
|
126
|
+
return response.body;
|
|
127
|
+
} catch (error) {
|
|
128
|
+
throw new Error(`failed to create secret: ${error.message}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
async listSecrets(namespace) {
|
|
132
|
+
try {
|
|
133
|
+
const response = await this.coreApi.listNamespacedSecret(namespace);
|
|
134
|
+
return { items: response.body.items || [] };
|
|
135
|
+
} catch (error) {
|
|
136
|
+
throw new Error(`failed to list secrets: ${error.message}`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
async getSecret(namespace, name) {
|
|
140
|
+
try {
|
|
141
|
+
const response = await this.coreApi.readNamespacedSecret(name, namespace);
|
|
142
|
+
return response.body;
|
|
143
|
+
} catch (error) {
|
|
144
|
+
throw new Error(`failed to get secret: ${error.message}`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
async deleteSecret(namespace, name) {
|
|
148
|
+
try {
|
|
149
|
+
await this.coreApi.deleteNamespacedSecret(name, namespace);
|
|
150
|
+
} catch (error) {
|
|
151
|
+
throw new Error(`failed to delete secret: ${error.message}`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
async createConfigMap(namespace, configMap) {
|
|
155
|
+
try {
|
|
156
|
+
const response = await this.coreApi.createNamespacedConfigMap(namespace, configMap);
|
|
157
|
+
return response.body;
|
|
158
|
+
} catch (error) {
|
|
159
|
+
throw new Error(`failed to create configmap: ${error.message}`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
async listConfigMaps(namespace, labelSelector) {
|
|
163
|
+
try {
|
|
164
|
+
const response = await this.coreApi.listNamespacedConfigMap(namespace, void 0, void 0, void 0, void 0, labelSelector);
|
|
165
|
+
return { items: response.body.items || [] };
|
|
166
|
+
} catch (error) {
|
|
167
|
+
throw new Error(`failed to list configmaps: ${error.message}`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
async getConfigMap(namespace, name) {
|
|
171
|
+
try {
|
|
172
|
+
const response = await this.coreApi.readNamespacedConfigMap(name, namespace);
|
|
173
|
+
return response.body;
|
|
174
|
+
} catch (error) {
|
|
175
|
+
throw new Error(`failed to get configmap: ${error.message}`);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
async updateConfigMap(namespace, name, configMap) {
|
|
179
|
+
try {
|
|
180
|
+
const response = await this.coreApi.replaceNamespacedConfigMap(name, namespace, configMap);
|
|
181
|
+
return response.body;
|
|
182
|
+
} catch (error) {
|
|
183
|
+
throw new Error(`failed to update configmap: ${error.message}`);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
async deleteConfigMap(namespace, name) {
|
|
187
|
+
try {
|
|
188
|
+
await this.coreApi.deleteNamespacedConfigMap(name, namespace);
|
|
189
|
+
} catch (error) {
|
|
190
|
+
throw new Error(`failed to delete configmap: ${error.message}`);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
async createCustomResource(group, version, namespace, plural, resource) {
|
|
194
|
+
try {
|
|
195
|
+
const response = await this.customApi.createNamespacedCustomObject(
|
|
196
|
+
group,
|
|
197
|
+
version,
|
|
198
|
+
namespace,
|
|
199
|
+
plural,
|
|
200
|
+
resource
|
|
201
|
+
);
|
|
202
|
+
return response.body;
|
|
203
|
+
} catch (error) {
|
|
204
|
+
const statusCode = error.response?.statusCode || error.statusCode;
|
|
205
|
+
const body = error.response?.body || error.body;
|
|
206
|
+
const message = body?.message || error.message;
|
|
207
|
+
const reason = body?.reason;
|
|
208
|
+
const details = body?.details;
|
|
209
|
+
console.error(`failed to create ${plural}:`, {
|
|
210
|
+
statusCode,
|
|
211
|
+
message,
|
|
212
|
+
reason,
|
|
213
|
+
details: JSON.stringify(details)
|
|
214
|
+
});
|
|
215
|
+
throw new Error(`failed to create ${plural}: ${message}${reason ? ` (${reason})` : ""}`);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
async deleteCustomResource(group, version, namespace, plural, name) {
|
|
219
|
+
try {
|
|
220
|
+
await this.customApi.deleteNamespacedCustomObject(
|
|
221
|
+
group,
|
|
222
|
+
version,
|
|
223
|
+
namespace,
|
|
224
|
+
plural,
|
|
225
|
+
name
|
|
226
|
+
);
|
|
227
|
+
} catch (error) {
|
|
228
|
+
throw new Error(`failed to delete ${plural}/${name}: ${error.message}`);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
async patchCustomResource(group, version, namespace, plural, name, patch) {
|
|
232
|
+
try {
|
|
233
|
+
const response = await this.customApi.patchNamespacedCustomObject(
|
|
234
|
+
group,
|
|
235
|
+
version,
|
|
236
|
+
namespace,
|
|
237
|
+
plural,
|
|
238
|
+
name,
|
|
239
|
+
patch
|
|
240
|
+
);
|
|
241
|
+
return response.body;
|
|
242
|
+
} catch (error) {
|
|
243
|
+
throw new Error(`failed to patch ${plural}/${name}: ${error.message}`);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
async patchCustomResourceStatus(group, version, namespace, plural, name, status) {
|
|
247
|
+
try {
|
|
248
|
+
const existing = await this.getCustomResource(group, version, namespace, plural, name);
|
|
249
|
+
const updated = {
|
|
250
|
+
...existing,
|
|
251
|
+
status
|
|
252
|
+
};
|
|
253
|
+
const response = await this.customApi.replaceNamespacedCustomObjectStatus(
|
|
254
|
+
group,
|
|
255
|
+
version,
|
|
256
|
+
namespace,
|
|
257
|
+
plural,
|
|
258
|
+
name,
|
|
259
|
+
updated
|
|
260
|
+
);
|
|
261
|
+
return response.body;
|
|
262
|
+
} catch (error) {
|
|
263
|
+
throw new Error(`failed to patch ${plural}/${name} status: ${error.message}`);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
exports.KuadrantK8sClient = KuadrantK8sClient;
|
|
269
|
+
//# sourceMappingURL=k8s-client.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"k8s-client.cjs.js","sources":["../src/k8s-client.ts"],"sourcesContent":["import * as k8s from '@kubernetes/client-node';\nimport { RootConfigService } from '@backstage/backend-plugin-api';\n\nexport interface K8sResource {\n apiVersion: string;\n kind: string;\n metadata: {\n name: string;\n namespace?: string;\n creationTimestamp?: string;\n labels?: Record<string, string>;\n annotations?: Record<string, string>;\n [key: string]: any;\n };\n spec?: any;\n status?: any;\n data?: any;\n stringData?: any;\n [key: string]: any;\n}\n\nexport interface K8sList {\n items: K8sResource[];\n}\n\nexport class KuadrantK8sClient {\n private kc: k8s.KubeConfig;\n private customApi: k8s.CustomObjectsApi;\n private coreApi: k8s.CoreV1Api;\n\n constructor(config: RootConfigService) {\n this.kc = new k8s.KubeConfig();\n\n const hasK8sConfig = config.has('kubernetes');\n\n if (hasK8sConfig) {\n const clusterLocatorMethods = config.getOptionalConfigArray('kubernetes.clusterLocatorMethods') || [];\n\n // look for type: config with explicit cluster configuration\n const configLocator = clusterLocatorMethods.find(c => c.getString('type') === 'config');\n\n if (configLocator) {\n const clusters = configLocator.getOptionalConfigArray('clusters') || [];\n\n if (clusters.length > 0) {\n // use the first cluster config\n const clusterConfig = clusters[0];\n const clusterName = clusterConfig.getString('name');\n const clusterUrl = clusterConfig.getString('url');\n const authProvider = clusterConfig.getOptionalString('authProvider');\n const skipTLSVerify = clusterConfig.getOptionalBoolean('skipTLSVerify') || false;\n\n if (authProvider === 'serviceAccount') {\n const serviceAccountToken = clusterConfig.getString('serviceAccountToken');\n\n // configure kubeconfig manually with service account\n const cluster = {\n name: clusterName,\n server: clusterUrl,\n skipTLSVerify: skipTLSVerify,\n };\n\n const user = {\n name: `${clusterName}-service-account`,\n token: serviceAccountToken,\n };\n\n const context = {\n name: `${clusterName}-context`,\n cluster: clusterName,\n user: user.name,\n };\n\n this.kc.loadFromOptions({\n clusters: [cluster],\n users: [user],\n contexts: [context],\n currentContext: context.name,\n });\n\n console.log(`k8s client initialised with explicit cluster config`);\n console.log(` cluster: ${clusterName}`);\n console.log(` url: ${clusterUrl}`);\n console.log(` auth: serviceAccount`);\n console.log(` skipTLSVerify: ${skipTLSVerify}`);\n } else {\n // unsupported auth provider, fall back to default\n console.log(`unsupported authProvider: ${authProvider}, falling back to default`);\n this.kc.loadFromDefault();\n }\n } else {\n // no clusters defined, fall back to default\n this.kc.loadFromDefault();\n this.logDefaultConfig('no clusters defined');\n }\n } else {\n // no type: config locator, fall back to default\n this.kc.loadFromDefault();\n this.logDefaultConfig('no config locator found');\n }\n } else {\n // no kubernetes config, use default (in-cluster or local kubeconfig)\n this.kc.loadFromDefault();\n this.logDefaultConfig('no kubernetes config in app-config.yaml');\n }\n\n this.customApi = this.kc.makeApiClient(k8s.CustomObjectsApi);\n this.coreApi = this.kc.makeApiClient(k8s.CoreV1Api);\n }\n\n private logDefaultConfig(reason: string): void {\n console.log(`k8s client initialised using default config (${reason})`);\n\n // determine if running in-cluster or using local kubeconfig\n const inClusterToken = process.env.KUBERNETES_SERVICE_HOST;\n\n if (inClusterToken) {\n console.log(' auth: in-cluster service account');\n console.log(' location: /var/run/secrets/kubernetes.io/serviceaccount/');\n } else {\n const kubeconfig = process.env.KUBECONFIG || '~/.kube/config';\n console.log(' auth: local kubeconfig');\n console.log(` location: ${kubeconfig}`);\n }\n }\n\n async listCustomResources(\n group: string,\n version: string,\n plural: string,\n namespace?: string,\n ): Promise<K8sList> {\n try {\n const response = namespace\n ? await this.customApi.listNamespacedCustomObject(group, version, namespace, plural)\n : await this.customApi.listClusterCustomObject(group, version, plural);\n\n return response.body as K8sList;\n } catch (error: any) {\n throw new Error(`failed to list ${plural}: ${error.message}`);\n }\n }\n\n async getCustomResource(\n group: string,\n version: string,\n namespace: string,\n plural: string,\n name: string,\n ): Promise<K8sResource> {\n try {\n const response = await this.customApi.getNamespacedCustomObject(\n group,\n version,\n namespace,\n plural,\n name,\n );\n return response.body as K8sResource;\n } catch (error: any) {\n throw new Error(`failed to get ${plural}/${name}: ${error.message}`);\n }\n }\n\n async createSecret(namespace: string, secret: K8sResource): Promise<K8sResource> {\n try {\n const response = await this.coreApi.createNamespacedSecret(namespace, secret as k8s.V1Secret);\n return response.body as K8sResource;\n } catch (error: any) {\n throw new Error(`failed to create secret: ${error.message}`);\n }\n }\n\n async listSecrets(namespace: string): Promise<K8sList> {\n try {\n const response = await this.coreApi.listNamespacedSecret(namespace);\n return { items: (response.body.items || []) as unknown as K8sResource[] };\n } catch (error: any) {\n throw new Error(`failed to list secrets: ${error.message}`);\n }\n }\n\n async getSecret(namespace: string, name: string): Promise<K8sResource> {\n try {\n const response = await this.coreApi.readNamespacedSecret(name, namespace);\n return response.body as K8sResource;\n } catch (error: any) {\n throw new Error(`failed to get secret: ${error.message}`);\n }\n }\n\n async deleteSecret(namespace: string, name: string): Promise<void> {\n try {\n await this.coreApi.deleteNamespacedSecret(name, namespace);\n } catch (error: any) {\n throw new Error(`failed to delete secret: ${error.message}`);\n }\n }\n\n async createConfigMap(namespace: string, configMap: K8sResource): Promise<K8sResource> {\n try {\n const response = await this.coreApi.createNamespacedConfigMap(namespace, configMap as k8s.V1ConfigMap);\n return response.body as K8sResource;\n } catch (error: any) {\n throw new Error(`failed to create configmap: ${error.message}`);\n }\n }\n\n async listConfigMaps(namespace: string, labelSelector?: string): Promise<K8sList> {\n try {\n const response = await this.coreApi.listNamespacedConfigMap(namespace, undefined, undefined, undefined, undefined, labelSelector);\n return { items: (response.body.items || []) as unknown as K8sResource[] };\n } catch (error: any) {\n throw new Error(`failed to list configmaps: ${error.message}`);\n }\n }\n\n async getConfigMap(namespace: string, name: string): Promise<K8sResource> {\n try {\n const response = await this.coreApi.readNamespacedConfigMap(name, namespace);\n return response.body as K8sResource;\n } catch (error: any) {\n throw new Error(`failed to get configmap: ${error.message}`);\n }\n }\n\n async updateConfigMap(namespace: string, name: string, configMap: K8sResource): Promise<K8sResource> {\n try {\n const response = await this.coreApi.replaceNamespacedConfigMap(name, namespace, configMap as k8s.V1ConfigMap);\n return response.body as K8sResource;\n } catch (error: any) {\n throw new Error(`failed to update configmap: ${error.message}`);\n }\n }\n\n async deleteConfigMap(namespace: string, name: string): Promise<void> {\n try {\n await this.coreApi.deleteNamespacedConfigMap(name, namespace);\n } catch (error: any) {\n throw new Error(`failed to delete configmap: ${error.message}`);\n }\n }\n\n async createCustomResource(\n group: string,\n version: string,\n namespace: string,\n plural: string,\n resource: K8sResource,\n ): Promise<K8sResource> {\n try {\n const response = await this.customApi.createNamespacedCustomObject(\n group,\n version,\n namespace,\n plural,\n resource as any,\n );\n return response.body as K8sResource;\n } catch (error: any) {\n // extract detailed error from kubernetes api response\n const statusCode = error.response?.statusCode || error.statusCode;\n const body = error.response?.body || error.body;\n const message = body?.message || error.message;\n const reason = body?.reason;\n const details = body?.details;\n\n console.error(`failed to create ${plural}:`, {\n statusCode,\n message,\n reason,\n details: JSON.stringify(details),\n });\n\n throw new Error(`failed to create ${plural}: ${message}${reason ? ` (${reason})` : ''}`);\n }\n }\n\n async deleteCustomResource(\n group: string,\n version: string,\n namespace: string,\n plural: string,\n name: string,\n ): Promise<void> {\n try {\n await this.customApi.deleteNamespacedCustomObject(\n group,\n version,\n namespace,\n plural,\n name,\n );\n } catch (error: any) {\n throw new Error(`failed to delete ${plural}/${name}: ${error.message}`);\n }\n }\n\n async patchCustomResource(\n group: string,\n version: string,\n namespace: string,\n plural: string,\n name: string,\n patch: any,\n ): Promise<K8sResource> {\n try {\n const response = await this.customApi.patchNamespacedCustomObject(\n group,\n version,\n namespace,\n plural,\n name,\n patch,\n );\n return response.body as K8sResource;\n } catch (error: any) {\n throw new Error(`failed to patch ${plural}/${name}: ${error.message}`);\n }\n }\n\n async patchCustomResourceStatus(\n group: string,\n version: string,\n namespace: string,\n plural: string,\n name: string,\n status: any,\n ): Promise<K8sResource> {\n try {\n // get the existing resource first\n const existing = await this.getCustomResource(group, version, namespace, plural, name);\n\n // replace the entire resource with updated status\n const updated = {\n ...existing,\n status,\n };\n\n const response = await this.customApi.replaceNamespacedCustomObjectStatus(\n group,\n version,\n namespace,\n plural,\n name,\n updated,\n );\n return response.body as K8sResource;\n } catch (error: any) {\n throw new Error(`failed to patch ${plural}/${name} status: ${error.message}`);\n }\n }\n}\n\n"],"names":["k8s"],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var pluginPermissionNode = require('@backstage/plugin-permission-node');
|
|
4
|
+
var permissions = require('./permissions.cjs.js');
|
|
5
|
+
|
|
6
|
+
function createKuadrantPermissionIntegrationRouter() {
|
|
7
|
+
return pluginPermissionNode.createPermissionIntegrationRouter({
|
|
8
|
+
permissions: permissions.kuadrantPermissions
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
exports.createKuadrantPermissionIntegrationRouter = createKuadrantPermissionIntegrationRouter;
|
|
13
|
+
//# sourceMappingURL=permissions-router.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissions-router.cjs.js","sources":["../src/permissions-router.ts"],"sourcesContent":["import { createPermissionIntegrationRouter as backstageCreatePermissionIntegrationRouter } from '@backstage/plugin-permission-node';\nimport { kuadrantPermissions } from './permissions';\n\n/**\n * creates a permission integration router that exposes kuadrant permissions\n * for discovery by rbac and other permission-aware plugins\n */\nexport function createKuadrantPermissionIntegrationRouter() {\n return backstageCreatePermissionIntegrationRouter({\n permissions: kuadrantPermissions,\n });\n}\n"],"names":["backstageCreatePermissionIntegrationRouter","kuadrantPermissions"],"mappings":";;;;;AAOO,SAAS,yCAA4C,GAAA;AAC1D,EAAA,OAAOA,sDAA2C,CAAA;AAAA,IAChD,WAAa,EAAAC;AAAA,GACd,CAAA;AACH;;;;"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var pluginPermissionCommon = require('@backstage/plugin-permission-common');
|
|
4
|
+
|
|
5
|
+
const kuadrantPlanPolicyCreatePermission = pluginPermissionCommon.createPermission({
|
|
6
|
+
name: "kuadrant.planpolicy.create",
|
|
7
|
+
attributes: { action: "create" }
|
|
8
|
+
});
|
|
9
|
+
const kuadrantPlanPolicyReadPermission = pluginPermissionCommon.createPermission({
|
|
10
|
+
name: "kuadrant.planpolicy.read",
|
|
11
|
+
attributes: { action: "read" }
|
|
12
|
+
});
|
|
13
|
+
const kuadrantPlanPolicyUpdatePermission = pluginPermissionCommon.createPermission({
|
|
14
|
+
name: "kuadrant.planpolicy.update",
|
|
15
|
+
attributes: { action: "update" }
|
|
16
|
+
});
|
|
17
|
+
const kuadrantPlanPolicyDeletePermission = pluginPermissionCommon.createPermission({
|
|
18
|
+
name: "kuadrant.planpolicy.delete",
|
|
19
|
+
attributes: { action: "delete" }
|
|
20
|
+
});
|
|
21
|
+
const kuadrantPlanPolicyListPermission = pluginPermissionCommon.createPermission({
|
|
22
|
+
name: "kuadrant.planpolicy.list",
|
|
23
|
+
attributes: { action: "read" }
|
|
24
|
+
});
|
|
25
|
+
const kuadrantApiProductCreatePermission = pluginPermissionCommon.createPermission({
|
|
26
|
+
name: "kuadrant.apiproduct.create",
|
|
27
|
+
attributes: { action: "create" }
|
|
28
|
+
});
|
|
29
|
+
const kuadrantApiProductReadPermission = pluginPermissionCommon.createPermission({
|
|
30
|
+
name: "kuadrant.apiproduct.read",
|
|
31
|
+
attributes: { action: "read" }
|
|
32
|
+
});
|
|
33
|
+
const kuadrantApiProductUpdatePermission = pluginPermissionCommon.createPermission({
|
|
34
|
+
name: "kuadrant.apiproduct.update",
|
|
35
|
+
attributes: { action: "update" }
|
|
36
|
+
});
|
|
37
|
+
const kuadrantApiProductDeletePermission = pluginPermissionCommon.createPermission({
|
|
38
|
+
name: "kuadrant.apiproduct.delete",
|
|
39
|
+
attributes: { action: "delete" }
|
|
40
|
+
});
|
|
41
|
+
const kuadrantApiProductListPermission = pluginPermissionCommon.createPermission({
|
|
42
|
+
name: "kuadrant.apiproduct.list",
|
|
43
|
+
attributes: { action: "read" }
|
|
44
|
+
});
|
|
45
|
+
const kuadrantApiKeyRequestCreatePermission = pluginPermissionCommon.createPermission({
|
|
46
|
+
name: "kuadrant.apikeyrequest.create",
|
|
47
|
+
attributes: { action: "create" },
|
|
48
|
+
resourceType: "apiproduct"
|
|
49
|
+
});
|
|
50
|
+
const kuadrantApiKeyRequestReadOwnPermission = pluginPermissionCommon.createPermission({
|
|
51
|
+
name: "kuadrant.apikeyrequest.read.own",
|
|
52
|
+
attributes: { action: "read" }
|
|
53
|
+
});
|
|
54
|
+
const kuadrantApiKeyRequestReadAllPermission = pluginPermissionCommon.createPermission({
|
|
55
|
+
name: "kuadrant.apikeyrequest.read.all",
|
|
56
|
+
attributes: { action: "read" }
|
|
57
|
+
});
|
|
58
|
+
const kuadrantApiKeyRequestUpdatePermission = pluginPermissionCommon.createPermission({
|
|
59
|
+
name: "kuadrant.apikeyrequest.update",
|
|
60
|
+
attributes: { action: "update" }
|
|
61
|
+
});
|
|
62
|
+
const kuadrantApiKeyRequestListPermission = pluginPermissionCommon.createPermission({
|
|
63
|
+
name: "kuadrant.apikeyrequest.list",
|
|
64
|
+
attributes: { action: "read" }
|
|
65
|
+
});
|
|
66
|
+
const kuadrantApiKeyReadOwnPermission = pluginPermissionCommon.createPermission({
|
|
67
|
+
name: "kuadrant.apikey.read.own",
|
|
68
|
+
attributes: { action: "read" }
|
|
69
|
+
});
|
|
70
|
+
const kuadrantApiKeyReadAllPermission = pluginPermissionCommon.createPermission({
|
|
71
|
+
name: "kuadrant.apikey.read.all",
|
|
72
|
+
attributes: { action: "read" }
|
|
73
|
+
});
|
|
74
|
+
const kuadrantApiKeyDeleteOwnPermission = pluginPermissionCommon.createPermission({
|
|
75
|
+
name: "kuadrant.apikey.delete.own",
|
|
76
|
+
attributes: { action: "delete" }
|
|
77
|
+
});
|
|
78
|
+
const kuadrantApiKeyDeleteAllPermission = pluginPermissionCommon.createPermission({
|
|
79
|
+
name: "kuadrant.apikey.delete.all",
|
|
80
|
+
attributes: { action: "delete" }
|
|
81
|
+
});
|
|
82
|
+
const kuadrantPermissions = [
|
|
83
|
+
kuadrantPlanPolicyCreatePermission,
|
|
84
|
+
kuadrantPlanPolicyReadPermission,
|
|
85
|
+
kuadrantPlanPolicyUpdatePermission,
|
|
86
|
+
kuadrantPlanPolicyDeletePermission,
|
|
87
|
+
kuadrantPlanPolicyListPermission,
|
|
88
|
+
kuadrantApiProductCreatePermission,
|
|
89
|
+
kuadrantApiProductReadPermission,
|
|
90
|
+
kuadrantApiProductUpdatePermission,
|
|
91
|
+
kuadrantApiProductDeletePermission,
|
|
92
|
+
kuadrantApiProductListPermission,
|
|
93
|
+
kuadrantApiKeyRequestCreatePermission,
|
|
94
|
+
kuadrantApiKeyRequestReadOwnPermission,
|
|
95
|
+
kuadrantApiKeyRequestReadAllPermission,
|
|
96
|
+
kuadrantApiKeyRequestUpdatePermission,
|
|
97
|
+
kuadrantApiKeyRequestListPermission,
|
|
98
|
+
kuadrantApiKeyReadOwnPermission,
|
|
99
|
+
kuadrantApiKeyReadAllPermission,
|
|
100
|
+
kuadrantApiKeyDeleteOwnPermission,
|
|
101
|
+
kuadrantApiKeyDeleteAllPermission
|
|
102
|
+
];
|
|
103
|
+
|
|
104
|
+
exports.kuadrantApiKeyDeleteAllPermission = kuadrantApiKeyDeleteAllPermission;
|
|
105
|
+
exports.kuadrantApiKeyDeleteOwnPermission = kuadrantApiKeyDeleteOwnPermission;
|
|
106
|
+
exports.kuadrantApiKeyReadAllPermission = kuadrantApiKeyReadAllPermission;
|
|
107
|
+
exports.kuadrantApiKeyReadOwnPermission = kuadrantApiKeyReadOwnPermission;
|
|
108
|
+
exports.kuadrantApiKeyRequestCreatePermission = kuadrantApiKeyRequestCreatePermission;
|
|
109
|
+
exports.kuadrantApiKeyRequestListPermission = kuadrantApiKeyRequestListPermission;
|
|
110
|
+
exports.kuadrantApiKeyRequestReadAllPermission = kuadrantApiKeyRequestReadAllPermission;
|
|
111
|
+
exports.kuadrantApiKeyRequestReadOwnPermission = kuadrantApiKeyRequestReadOwnPermission;
|
|
112
|
+
exports.kuadrantApiKeyRequestUpdatePermission = kuadrantApiKeyRequestUpdatePermission;
|
|
113
|
+
exports.kuadrantApiProductCreatePermission = kuadrantApiProductCreatePermission;
|
|
114
|
+
exports.kuadrantApiProductDeletePermission = kuadrantApiProductDeletePermission;
|
|
115
|
+
exports.kuadrantApiProductListPermission = kuadrantApiProductListPermission;
|
|
116
|
+
exports.kuadrantApiProductReadPermission = kuadrantApiProductReadPermission;
|
|
117
|
+
exports.kuadrantApiProductUpdatePermission = kuadrantApiProductUpdatePermission;
|
|
118
|
+
exports.kuadrantPermissions = kuadrantPermissions;
|
|
119
|
+
exports.kuadrantPlanPolicyCreatePermission = kuadrantPlanPolicyCreatePermission;
|
|
120
|
+
exports.kuadrantPlanPolicyDeletePermission = kuadrantPlanPolicyDeletePermission;
|
|
121
|
+
exports.kuadrantPlanPolicyListPermission = kuadrantPlanPolicyListPermission;
|
|
122
|
+
exports.kuadrantPlanPolicyReadPermission = kuadrantPlanPolicyReadPermission;
|
|
123
|
+
exports.kuadrantPlanPolicyUpdatePermission = kuadrantPlanPolicyUpdatePermission;
|
|
124
|
+
//# sourceMappingURL=permissions.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissions.cjs.js","sources":["../src/permissions.ts"],"sourcesContent":["import { createPermission } from '@backstage/plugin-permission-common';\n\n/**\n * Permission definitions for the Kuadrant plugin\n *\n * These permissions control access to PlanPolicy, APIProduct, APIKeyRequest,\n * and API key management within the Kuadrant Backstage plugin.\n *\n * Permissions are composable - use them to build custom roles beyond the\n * three reference personas (Platform Engineer, API Owner, API Consumer).\n */\n\n// planpolicy permissions (rate limit tiers)\nexport const kuadrantPlanPolicyCreatePermission = createPermission({\n name: 'kuadrant.planpolicy.create',\n attributes: { action: 'create' },\n});\n\nexport const kuadrantPlanPolicyReadPermission = createPermission({\n name: 'kuadrant.planpolicy.read',\n attributes: { action: 'read' },\n});\n\nexport const kuadrantPlanPolicyUpdatePermission = createPermission({\n name: 'kuadrant.planpolicy.update',\n attributes: { action: 'update' },\n});\n\nexport const kuadrantPlanPolicyDeletePermission = createPermission({\n name: 'kuadrant.planpolicy.delete',\n attributes: { action: 'delete' },\n});\n\nexport const kuadrantPlanPolicyListPermission = createPermission({\n name: 'kuadrant.planpolicy.list',\n attributes: { action: 'read' },\n});\n\n// apiproduct permissions (catalog entries)\nexport const kuadrantApiProductCreatePermission = createPermission({\n name: 'kuadrant.apiproduct.create',\n attributes: { action: 'create' },\n});\n\nexport const kuadrantApiProductReadPermission = createPermission({\n name: 'kuadrant.apiproduct.read',\n attributes: { action: 'read' },\n});\n\nexport const kuadrantApiProductUpdatePermission = createPermission({\n name: 'kuadrant.apiproduct.update',\n attributes: { action: 'update' },\n});\n\nexport const kuadrantApiProductDeletePermission = createPermission({\n name: 'kuadrant.apiproduct.delete',\n attributes: { action: 'delete' },\n});\n\nexport const kuadrantApiProductListPermission = createPermission({\n name: 'kuadrant.apiproduct.list',\n attributes: { action: 'read' },\n});\n\n// apikeyrequest permissions (access requests)\nexport const kuadrantApiKeyRequestCreatePermission = createPermission({\n name: 'kuadrant.apikeyrequest.create',\n attributes: { action: 'create' },\n resourceType: 'apiproduct',\n});\n\nexport const kuadrantApiKeyRequestReadOwnPermission = createPermission({\n name: 'kuadrant.apikeyrequest.read.own',\n attributes: { action: 'read' },\n});\n\nexport const kuadrantApiKeyRequestReadAllPermission = createPermission({\n name: 'kuadrant.apikeyrequest.read.all',\n attributes: { action: 'read' },\n});\n\nexport const kuadrantApiKeyRequestUpdatePermission = createPermission({\n name: 'kuadrant.apikeyrequest.update',\n attributes: { action: 'update' },\n});\n\nexport const kuadrantApiKeyRequestListPermission = createPermission({\n name: 'kuadrant.apikeyrequest.list',\n attributes: { action: 'read' },\n});\n\n// api key permissions (managed secrets)\nexport const kuadrantApiKeyReadOwnPermission = createPermission({\n name: 'kuadrant.apikey.read.own',\n attributes: { action: 'read' },\n});\n\nexport const kuadrantApiKeyReadAllPermission = createPermission({\n name: 'kuadrant.apikey.read.all',\n attributes: { action: 'read' },\n});\n\nexport const kuadrantApiKeyDeleteOwnPermission = createPermission({\n name: 'kuadrant.apikey.delete.own',\n attributes: { action: 'delete' },\n});\n\nexport const kuadrantApiKeyDeleteAllPermission = createPermission({\n name: 'kuadrant.apikey.delete.all',\n attributes: { action: 'delete' },\n});\n\n/**\n * All Kuadrant permissions as an array for easy iteration\n */\nexport const kuadrantPermissions = [\n kuadrantPlanPolicyCreatePermission,\n kuadrantPlanPolicyReadPermission,\n kuadrantPlanPolicyUpdatePermission,\n kuadrantPlanPolicyDeletePermission,\n kuadrantPlanPolicyListPermission,\n kuadrantApiProductCreatePermission,\n kuadrantApiProductReadPermission,\n kuadrantApiProductUpdatePermission,\n kuadrantApiProductDeletePermission,\n kuadrantApiProductListPermission,\n kuadrantApiKeyRequestCreatePermission,\n kuadrantApiKeyRequestReadOwnPermission,\n kuadrantApiKeyRequestReadAllPermission,\n kuadrantApiKeyRequestUpdatePermission,\n kuadrantApiKeyRequestListPermission,\n kuadrantApiKeyReadOwnPermission,\n kuadrantApiKeyReadAllPermission,\n kuadrantApiKeyDeleteOwnPermission,\n kuadrantApiKeyDeleteAllPermission,\n];\n"],"names":["createPermission"],"mappings":"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"}
|