fix(image registry): start work on image registry
This commit is contained in:
@ -3,6 +3,6 @@
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@serve.zone/cloudly',
|
||||
version: '1.1.0',
|
||||
version: '1.1.1',
|
||||
description: 'A cloud manager leveraging Docker Swarmkit for multi-cloud operations including DigitalOcean, Hetzner Cloud, and Cloudflare, with integration support and robust configuration management system.'
|
||||
}
|
||||
|
@ -10,9 +10,6 @@ export class CloudlyConfig {
|
||||
public cloudlyRef: Cloudly;
|
||||
public appData: plugins.npmextra.AppData<plugins.servezoneInterfaces.data.ICloudlyConfig>;
|
||||
public data: plugins.servezoneInterfaces.data.ICloudlyConfig
|
||||
|
||||
// authentication and settings
|
||||
public smartjwtInstance: plugins.smartjwt.SmartJwt;
|
||||
|
||||
|
||||
constructor(cloudlyRefArg: Cloudly) {
|
||||
|
@ -34,7 +34,10 @@ export class LetsencryptConnector {
|
||||
},
|
||||
mongoDescriptor: this.cloudlyRef.config.data.mongoDescriptor,
|
||||
});
|
||||
await this.smartacme.init();
|
||||
await this.smartacme.init().catch(err => {
|
||||
console.error('error in init', err);
|
||||
console.log(`trying again in a few minutes`)
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
13
ts/demo/demo.data.images.ts
Normal file
13
ts/demo/demo.data.images.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import * as plugins from '../plugins.js';
|
||||
|
||||
export const demoImages: plugins.servezoneInterfaces.data.IImage[] = [
|
||||
{
|
||||
id: 'DemoImage1',
|
||||
data: {
|
||||
name: 'DemoImage1',
|
||||
description: 'DemoImage1',
|
||||
versions: [],
|
||||
}
|
||||
}
|
||||
];
|
||||
|
@ -1,9 +1,12 @@
|
||||
export const users = [
|
||||
import * as plugins from '../plugins.js';
|
||||
|
||||
export const users: plugins.servezoneInterfaces.data.IUser[] = [
|
||||
{
|
||||
id: 'user1',
|
||||
data: {
|
||||
username: 'admin',
|
||||
password: 'password',
|
||||
role: 'admin',
|
||||
}
|
||||
}
|
||||
]
|
@ -48,4 +48,18 @@ export const installDemoData = async (cloudlyRef: Cloudly) => {
|
||||
Object.assign(userInstance, user);
|
||||
await userInstance.save();
|
||||
}
|
||||
|
||||
// ================================================================================
|
||||
// IMAGES
|
||||
const images = await cloudlyRef.imageManager.CImage.getInstances({});
|
||||
for (const image of images) {
|
||||
await image.delete();
|
||||
}
|
||||
|
||||
const demoDataImages = await import('./demo.data.images.js');
|
||||
for (const image of demoDataImages.demoImages) {
|
||||
const imageInstance = new cloudlyRef.imageManager.CImage();
|
||||
Object.assign(imageInstance, image);
|
||||
await imageInstance.save();
|
||||
}
|
||||
}
|
@ -30,6 +30,7 @@ export class CloudlyAuthManager {
|
||||
public async start() {
|
||||
// lets setup the smartjwtInstance
|
||||
this.smartjwtInstance = new plugins.smartjwt.SmartJwt();
|
||||
await this.smartjwtInstance.init();
|
||||
const kvStore = await this.cloudlyRef.config.appData.getKvStore();
|
||||
|
||||
const existingJwtKeys: plugins.tsclass.network.IJwtKeypair = await kvStore.readKey('jwtKeys');
|
||||
@ -51,7 +52,7 @@ export class CloudlyAuthManager {
|
||||
if (!user) {
|
||||
logger.log('warn', 'login failed');
|
||||
} else {
|
||||
jwt = await this.cloudlyRef.config.smartjwtInstance.createJWT({
|
||||
jwt = await this.smartjwtInstance.createJWT({
|
||||
userId: user.id,
|
||||
status: 'loggedIn',
|
||||
});
|
||||
@ -69,8 +70,12 @@ export class CloudlyAuthManager {
|
||||
|
||||
public adminJwtGuard = new plugins.smartguard.Guard<{jwt: string}>(async (dataArg) => {
|
||||
const jwt = dataArg.jwt;
|
||||
const jwtData: IJwtData = await this.cloudlyRef.config.smartjwtInstance.verifyJWTAndGetData(jwt);
|
||||
const jwtData: IJwtData = await this.smartjwtInstance.verifyJWTAndGetData(jwt);
|
||||
const user = await this.CUser.getInstance({id: jwtData.userId});
|
||||
return user.data.role === 'admin';
|
||||
const isAdminBool = user.data.role === 'admin';
|
||||
console.log(`user is admin: ${isAdminBool}`);
|
||||
return isAdminBool;
|
||||
}, {
|
||||
failedHint: 'user is not admin.'
|
||||
})
|
||||
}
|
@ -1,13 +1,16 @@
|
||||
import * as plugins from '../plugins.js';
|
||||
|
||||
@plugins.smartdata.managed()
|
||||
export class User extends plugins.smartdata.SmartDataDbDoc<User, User> {
|
||||
export class User extends plugins.smartdata.SmartDataDbDoc<
|
||||
User,
|
||||
plugins.servezoneInterfaces.data.IUser
|
||||
> {
|
||||
public static async findUserByUsernameAndPassword(usernameArg: string, passwordArg: string) {
|
||||
return await User.getInstance({
|
||||
data: {
|
||||
username: usernameArg,
|
||||
password: passwordArg,
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@ -20,5 +23,5 @@ export class User extends plugins.smartdata.SmartDataDbDoc<User, User> {
|
||||
role: 'admin' | 'user';
|
||||
username: string;
|
||||
password: string;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -26,8 +26,12 @@ export class CloudlyCoreflowManager {
|
||||
|
||||
return {
|
||||
clusterIdentifier: {
|
||||
clusterId: clusterConfig.id,
|
||||
clusterName: clusterConfig.data.name,
|
||||
secretKey: clusterConfig.data.secretKey,
|
||||
jwt: await this.cloudlyRef.authManager.smartjwtInstance.createJWT({
|
||||
status: 'loggedIn',
|
||||
userId: 'cluster:' + clusterConfig.id, // TODO: create real users for clusters
|
||||
})
|
||||
},
|
||||
};
|
||||
})
|
||||
@ -47,7 +51,8 @@ export class CloudlyCoreflowManager {
|
||||
);
|
||||
console.log('got cluster config and sending it back to coreflow');
|
||||
return {
|
||||
configData: await clusterConfigSet.createSavableObject()
|
||||
configData: await clusterConfigSet.createSavableObject(),
|
||||
deploymentDirectives: [],
|
||||
};
|
||||
}
|
||||
)
|
||||
|
@ -1,12 +1,20 @@
|
||||
import * as plugins from '../plugins.js';
|
||||
import type { ImageManager } from './classes.imagemanager.js';
|
||||
|
||||
@plugins.smartdata.Manager()
|
||||
@plugins.smartdata.managed()
|
||||
export class Image extends plugins.smartdata.SmartDataDbDoc<Image, plugins.servezoneInterfaces.data.IImage, ImageManager> {
|
||||
public static async create(imageDataArg: Partial<plugins.servezoneInterfaces.data.IImage['data']>) {
|
||||
const image = new Image();
|
||||
image.id = plugins.smartunique.uni('image');
|
||||
Object.assign(image.data, imageDataArg);
|
||||
image.id = await this.getNewId();
|
||||
console.log(imageDataArg);
|
||||
Object.assign(image, {
|
||||
data: {
|
||||
name: imageDataArg.name,
|
||||
description: imageDataArg.description,
|
||||
versions: [],
|
||||
},
|
||||
});
|
||||
console.log((Image as any).saveableProperties)
|
||||
await image.save();
|
||||
return image;
|
||||
}
|
||||
|
@ -5,19 +5,52 @@ import { Image } from './classes.image.js';
|
||||
|
||||
export class ImageManager {
|
||||
cloudlyRef: Cloudly;
|
||||
public typedrouter = new plugins.typedrequest.TypedRouter();
|
||||
public smartbucketInstance: plugins.smartbucket.SmartBucket;
|
||||
|
||||
get db() {
|
||||
return this.cloudlyRef.mongodbConnector.smartdataDb;
|
||||
}
|
||||
public typedrouter = new plugins.typedrequest.TypedRouter();
|
||||
|
||||
public CImage = plugins.smartdata.setDefaultManagerForDoc(this, Image);
|
||||
|
||||
smartbucketInstance: plugins.smartbucket.SmartBucket;
|
||||
|
||||
constructor(cloudlyRefArg: Cloudly) {
|
||||
this.cloudlyRef = cloudlyRefArg;
|
||||
|
||||
this.cloudlyRef.typedrouter.addTypedRouter(this.typedrouter);
|
||||
|
||||
this.typedrouter.addTypedHandler(
|
||||
new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.image.IRequest_CreateImage>(
|
||||
'createImage',
|
||||
async (reqArg, toolsArg) => {
|
||||
await toolsArg.passGuards([this.cloudlyRef.authManager.adminJwtGuard], reqArg);
|
||||
const image = await this.CImage.create({
|
||||
name: reqArg.name,
|
||||
description: reqArg.description,
|
||||
versions: [],
|
||||
});
|
||||
return {
|
||||
image: await image.createSavableObject(),
|
||||
};
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
this.typedrouter.addTypedHandler(
|
||||
new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.image.IRequest_DeleteImage>(
|
||||
'deleteImage',
|
||||
async (reqArg, toolsArg) => {
|
||||
await toolsArg.passGuards([this.cloudlyRef.authManager.adminJwtGuard], reqArg);
|
||||
const image = await this.CImage.getInstance({
|
||||
id: reqArg.imageId,
|
||||
});
|
||||
await image.delete();
|
||||
return {};
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
this.typedrouter.addTypedHandler(
|
||||
new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.image.IRequest_GetAllImages>(
|
||||
'getAllImages',
|
||||
@ -36,22 +69,8 @@ export class ImageManager {
|
||||
);
|
||||
|
||||
this.typedrouter.addTypedHandler(
|
||||
new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.image.IRequest_CreateImage>(
|
||||
'createImage',
|
||||
async (reqArg) => {
|
||||
const image = await this.CImage.create({
|
||||
name: reqArg.name,
|
||||
});
|
||||
return {
|
||||
image: await image.createSavableObject(),
|
||||
};
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
this.typedrouter.addTypedHandler(
|
||||
new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.image.IRequest_PushImage>(
|
||||
'pushImage',
|
||||
new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.image.IRequest_PushImageVersion>(
|
||||
'pushImageVersion',
|
||||
async (reqArg) => {
|
||||
const pushStream = reqArg.imageStream;
|
||||
return {};
|
||||
@ -60,8 +79,8 @@ export class ImageManager {
|
||||
);
|
||||
|
||||
this.typedrouter.addTypedHandler(
|
||||
new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.image.IRequest_PullImage>(
|
||||
'pullImage',
|
||||
new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.image.IRequest_PullImageVersion>(
|
||||
'pullImageVersion',
|
||||
async (reqArg) => {
|
||||
const image = await this.CImage.getInstance({
|
||||
data: {
|
||||
|
@ -38,7 +38,8 @@ export class CloudlySecretManager {
|
||||
this.typedrouter.addTypedHandler(
|
||||
new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.secret.IReq_Admin_GetConfigBundlesAndSecretGroups>(
|
||||
'adminGetConfigBundlesAndSecretGroups',
|
||||
async (dataArg) => {
|
||||
async (dataArg, toolsArg) => {
|
||||
await toolsArg.passGuards([this.cloudlyRef.authManager.adminJwtGuard], dataArg);
|
||||
dataArg.jwt
|
||||
const secretBundles = await SecretBundle.getInstances({});
|
||||
const secretGroups = await SecretGroup.getInstances({});
|
||||
|
Reference in New Issue
Block a user