Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/cli/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { cmdChat } from './architect/cmd';
import { cmdVod } from './vod/cmd';
import { cmdWeb } from './web/cmd';
import { cmdLogin } from './login';
import { cmdMyapp } from './myapp/cmd';
import { ensureToken } from './user/util';

const cli = new Command();
Expand Down Expand Up @@ -65,4 +66,5 @@ cli.addCommand(cmdDb());
cli.addCommand(cmdChat());
cli.addCommand(cmdVod());
cli.addCommand(cmdWeb());
cli.addCommand(cmdMyapp());
cli.parse(process.argv);
99 changes: 99 additions & 0 deletions packages/cli/src/myapp/cmd.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import { Command } from 'commander';
import {
Context,
listMyApps,
createMyApp,
getMyApp,
removeMyApp
} from '@osaas/client-core';
import { confirm } from '../user/util';

export function cmdMyapp() {
const myapp = new Command('myapp');

myapp
.command('list')
.description('List all my apps')
.action(async (options, command) => {
try {
const globalOpts = command.optsWithGlobals();
const environment = globalOpts?.env || 'prod';
const ctx = new Context({ environment });
const apps = await listMyApps(ctx);
apps.forEach((app) => {
console.log(`${app.name} (${app.type}): ${app.url || 'no url yet'}`);
});
} catch (err) {
console.log((err as Error).message);
}
});

myapp
.command('create')
.description('Create a new app')
.argument('<name>', 'App name')
.argument('<type>', 'App type (nodejs or python)')
.argument('<gitHubUrl>', 'GitHub repository URL')
.option('--github-token <token>', 'GitHub token for private repos')
.option('--config-service <name>', 'Config service reference')
.action(async (name, type, gitHubUrl, options, command) => {
try {
const globalOpts = command.optsWithGlobals();
const environment = globalOpts?.env || 'prod';
const ctx = new Context({ environment });
const app = await createMyApp(ctx, {
name,
type,
gitHubUrl,
gitHubToken: options.githubToken,
configService: options.configService
});
console.log(`App ${app.name} created successfully.`);
if (app.appDns) {
console.log(`DNS: ${app.appDns}`);
}
} catch (err) {
console.log((err as Error).message);
}
});

myapp
.command('describe')
.description('Show app details')
.argument('<appId>', 'App ID')
.action(async (appId, options, command) => {
try {
const globalOpts = command.optsWithGlobals();
const environment = globalOpts?.env || 'prod';
const ctx = new Context({ environment });
const app = await getMyApp(ctx, appId);
console.log(JSON.stringify(app, null, 2));
} catch (err) {
console.log((err as Error).message);
}
});

myapp
.command('remove')
.description('Remove an app')
.argument('<appId>', 'App ID')
.option('-y, --yes', 'Skip confirmation')
.action(async (appId, options, command) => {
try {
if (!options.yes) {
await confirm(
`Are you sure you want to remove app ${appId}? (yes/no) `
);
}
const globalOpts = command.optsWithGlobals();
const environment = globalOpts?.env || 'prod';
const ctx = new Context({ environment });
await removeMyApp(ctx, appId);
console.log(`App ${appId} removed successfully.`);
} catch (err) {
console.log((err as Error).message);
}
});

return myapp;
}
1 change: 1 addition & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,4 @@ export {
} from './job';
export * from './platform/maker';
export * from './errors';
export * from './myapp';
77 changes: 77 additions & 0 deletions packages/core/src/myapp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { Context } from './context';
import { createFetch } from './fetch';

export type MyApp = {
id: string;
name: string;
type: string;
gitHubUrl: string;
url: string;
appDns: string;
tenantId: string;
};

export type CreateMyAppBody = {
name: string;
type: string;
gitHubUrl: string;
gitHubToken?: string;
configService?: string;
};

export async function listMyApps(ctx: Context): Promise<MyApp[]> {
const url = new URL(
'/myapps',
`https://deploy.svc.${ctx.getEnvironment()}.osaas.io`
);
return await createFetch<MyApp[]>(url, {
method: 'GET',
headers: {
'x-pat-jwt': `Bearer ${ctx.getPersonalAccessToken()}`
}
});
}

export async function createMyApp(
ctx: Context,
body: CreateMyAppBody
): Promise<MyApp> {
const url = new URL(
'/myapps',
`https://deploy.svc.${ctx.getEnvironment()}.osaas.io`
);
return await createFetch<MyApp>(url, {
method: 'POST',
headers: {
'x-pat-jwt': `Bearer ${ctx.getPersonalAccessToken()}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
});
}

export async function getMyApp(ctx: Context, appId: string): Promise<MyApp> {
const url = new URL(
`/myapps/${appId}`,
`https://deploy.svc.${ctx.getEnvironment()}.osaas.io`
);
return await createFetch<MyApp>(url, {
method: 'GET',
headers: {
'x-pat-jwt': `Bearer ${ctx.getPersonalAccessToken()}`
}
});
}

export async function removeMyApp(ctx: Context, appId: string): Promise<void> {
const url = new URL(
`/myapps/${appId}`,
`https://deploy.svc.${ctx.getEnvironment()}.osaas.io`
);
await createFetch<void>(url, {
method: 'DELETE',
headers: {
'x-pat-jwt': `Bearer ${ctx.getPersonalAccessToken()}`
}
});
}
68 changes: 68 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,74 @@ const instance = await createInstance(
console.log(instance.url);
```

### Managing Custom Applications

You can deploy and manage custom applications (Node.js or Python) from GitHub repositories using the CLI or the SDK.

#### CLI

List all your deployed apps:

```
osc myapp list
```

Deploy a new app from a GitHub repository:

```
osc myapp create <name> <type> <gitHubUrl>
```

Where `type` is either `nodejs` or `python`. For private repositories you can provide a GitHub token:

```
osc myapp create myapp nodejs https://github.com/user/repo --github-token <token>
```

You can also attach a config service:

```
osc myapp create myapp nodejs https://github.com/user/repo --config-service <name>
```

Get details about an app:

```
osc myapp describe <appId>
```

Remove an app:

```
osc myapp remove <appId>
```

Use the `-y` flag to skip the confirmation prompt.

#### SDK

```javascript
import { Context, listMyApps, createMyApp, getMyApp, removeMyApp } from '@osaas/client-core';

const ctx = new Context();

// List all apps
const apps = await listMyApps(ctx);

// Create a new app
const app = await createMyApp(ctx, {
name: 'myapp',
type: 'nodejs',
gitHubUrl: 'https://github.com/user/repo'
});

// Get app details
const details = await getMyApp(ctx, app.id);

// Remove an app
await removeMyApp(ctx, app.id);
```

### What is Open Source Cloud?

A software as a service based on open source with a unique transparent model where revenue is shared with the open source authors. Open Source Cloud offers media industry companies a quick way to incorporate open source in their solutions and the option to run the same software in-house as the source code is publicly available.
Expand Down