fix: allow coreflow deployment input reads
This commit is contained in:
@@ -246,6 +246,54 @@ tap.test('should push service config updates to connected coreflows', async (too
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
tap.test('should allow cluster coreflows to read deployment inputs', async () => {
|
||||||
|
const cluster = await testClient.cluster.createCluster('Registry Coreflow Read Test Cluster');
|
||||||
|
const persistedCluster = await testCloudly.clusterManager.getConfigBy_ConfigID(cluster.id);
|
||||||
|
const clusterUser = await testCloudly.authManager.CUser.getInstance({
|
||||||
|
id: persistedCluster.data.userId,
|
||||||
|
});
|
||||||
|
const clusterToken = clusterUser.data.tokens?.[0]?.token;
|
||||||
|
expect(clusterToken).toBeTruthy();
|
||||||
|
|
||||||
|
const image = await testClient.image.createImage({
|
||||||
|
name: 'Registry Coreflow Read Test Image',
|
||||||
|
description: 'Image used by the coreflow read test',
|
||||||
|
});
|
||||||
|
const secretBundle = await testClient.secretbundle.createSecretBundle({
|
||||||
|
name: 'Registry Coreflow Read Test Secret Bundle',
|
||||||
|
description: 'Secret bundle used by the coreflow read test',
|
||||||
|
type: 'service',
|
||||||
|
includedSecretGroupIds: [],
|
||||||
|
includedTags: [],
|
||||||
|
imageClaims: [],
|
||||||
|
authorizations: [
|
||||||
|
{
|
||||||
|
environment: 'production',
|
||||||
|
secretAccessKey: 'registry-coreflow-read-test',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const coreflowClient = new cloudlyApiClient.CloudlyApiClient({
|
||||||
|
registerAs: 'coreflow',
|
||||||
|
cloudlyUrl: `http://${helpers.testCloudlyConfig.publicUrl}:${helpers.testCloudlyConfig.publicPort}`,
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
await coreflowClient.start();
|
||||||
|
await coreflowClient.getIdentityByToken(clusterToken!, {
|
||||||
|
statefullIdentity: true,
|
||||||
|
tagConnection: true,
|
||||||
|
});
|
||||||
|
const clusterImage = await coreflowClient.image.getImageById(image.id);
|
||||||
|
const clusterSecretBundle = await coreflowClient.secretbundle.getSecretBundleById(secretBundle.id);
|
||||||
|
expect(clusterImage.id).toEqual(image.id);
|
||||||
|
expect(clusterSecretBundle.id).toEqual(secretBundle.id);
|
||||||
|
} finally {
|
||||||
|
await coreflowClient.stop();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
tap.test('should expose platform desired state', async () => {
|
tap.test('should expose platform desired state', async () => {
|
||||||
const capabilitiesResponse = await testClient.platform.getPlatformCapabilities();
|
const capabilitiesResponse = await testClient.platform.getPlatformCapabilities();
|
||||||
expect(capabilitiesResponse.capabilities.find((capability) => capability.id === 'database')).toBeTruthy();
|
expect(capabilitiesResponse.capabilities.find((capability) => capability.id === 'database')).toBeTruthy();
|
||||||
|
|||||||
@@ -172,4 +172,20 @@ export class CloudlyAuthManager {
|
|||||||
name: 'adminIdentityGuard',
|
name: 'adminIdentityGuard',
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
public adminOrClusterIdentityGuard = new plugins.smartguard.Guard<{
|
||||||
|
identity: plugins.servezoneInterfaces.data.IIdentity;
|
||||||
|
}>(
|
||||||
|
async (dataArg) => {
|
||||||
|
await plugins.smartguard.passGuardsOrReject(dataArg, [this.validIdentityGuard]);
|
||||||
|
const jwt = dataArg.identity.jwt;
|
||||||
|
const jwtData: IJwtData = await this.smartjwtInstance.verifyJWTAndGetData(jwt);
|
||||||
|
const user = await this.CUser.getInstance({ id: jwtData.userId });
|
||||||
|
return user.data.role === 'admin' || user.data.role === 'cluster';
|
||||||
|
},
|
||||||
|
{
|
||||||
|
failedHint: 'user is not admin or cluster.',
|
||||||
|
name: 'adminOrClusterIdentityGuard',
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ export class ImageManager {
|
|||||||
|
|
||||||
this.typedrouter.addTypedHandler<plugins.servezoneInterfaces.requests.image.IRequest_GetImage>(
|
this.typedrouter.addTypedHandler<plugins.servezoneInterfaces.requests.image.IRequest_GetImage>(
|
||||||
new plugins.typedrequest.TypedHandler('getImage', async (reqArg, toolsArg) => {
|
new plugins.typedrequest.TypedHandler('getImage', async (reqArg, toolsArg) => {
|
||||||
await toolsArg.passGuards([this.cloudlyRef.authManager.adminIdentityGuard], reqArg);
|
await toolsArg.passGuards([this.cloudlyRef.authManager.adminOrClusterIdentityGuard], reqArg);
|
||||||
const image = await this.CImage.getInstance({
|
const image = await this.CImage.getInstance({
|
||||||
id: reqArg.imageId,
|
id: reqArg.imageId,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -54,6 +54,18 @@ export class CloudlySecretManager {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.typedrouter.addTypedHandler<plugins.servezoneInterfaces.requests.secretbundle.IReq_GetSecretBundleById>(
|
||||||
|
new plugins.typedrequest.TypedHandler('getSecretBundleById', async (dataArg, toolsArg) => {
|
||||||
|
await toolsArg.passGuards([this.cloudlyRef.authManager.adminOrClusterIdentityGuard], dataArg);
|
||||||
|
const secretBundle = await SecretBundle.getInstance({
|
||||||
|
id: dataArg.secretBundleId,
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
secretBundle: await secretBundle.createSavableObject(),
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
this.typedrouter.addTypedHandler<plugins.servezoneInterfaces.requests.secretbundle.IReq_CreateSecretBundle>(
|
this.typedrouter.addTypedHandler<plugins.servezoneInterfaces.requests.secretbundle.IReq_CreateSecretBundle>(
|
||||||
new plugins.typedrequest.TypedHandler('createSecretBundle', async (dataArg) => {
|
new plugins.typedrequest.TypedHandler('createSecretBundle', async (dataArg) => {
|
||||||
const secretBundle = new SecretBundle();
|
const secretBundle = new SecretBundle();
|
||||||
|
|||||||
Reference in New Issue
Block a user