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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ ServerlessInsight supports the following cloud providers:
| ----------------- | ---------------- | -------------- | -------------- | ---------------- | ------- |
| **Alibaba Cloud** | ✅ FC3 | ✅ API Gateway | ✅ OSS | ✅ RDS, OTS, ESS | Stable |
| **Tencent Cloud** | ✅ SCF | 🚧 Coming Soon | ✅ COS | ✅ TDSQL-C | Stable |
| **Volcengine** | ✅ veFaaS | ✅ API Gateway | ✅ TOS | — | Stable |
| **Huawei Cloud** | ✅ FunctionGraph | 🚧 Coming Soon | 🚧 Coming Soon | 🚧 Coming Soon | Beta |
| **AWS** | 🔜 Planned | 🔜 Planned | 🔜 Planned | 🔜 Planned | Planned |
| **Azure** | 🔜 Planned | 🔜 Planned | 🔜 Planned | 🔜 Planned | Planned |
Expand Down
31 changes: 31 additions & 0 deletions samples/volcengine-poc-api.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
version: 0.1.0
provider:
name: volcengine
region: cn-beijing

app: insight-poc
service: insight-poc-api

functions:
api_function:
name: insight-poc-api-fn
code:
runtime: nodejs/v18
handler: index.handler
path: ./artifacts/function.zip
memory: 256
timeout: 30
environment:
NODE_ENV: production

events:
api_gateway:
type: API_GATEWAY
name: insight-poc-api
triggers:
- method: GET
path: /api/hello
backend: ${functions.api_function}
- method: POST
path: /api/data
backend: ${functions.api_function}
17 changes: 17 additions & 0 deletions samples/volcengine-poc-bucket.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
version: 0.1.0
provider:
name: volcengine
region: cn-beijing

app: insight-poc
service: insight-poc-bucket

buckets:
website_bucket:
name: insight-poc-website
security:
acl: PUBLIC_READ
website:
code: ./dist
index: index.html
error_page: 404.html
19 changes: 19 additions & 0 deletions samples/volcengine-poc-function.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
version: 0.1.0
provider:
name: volcengine
region: cn-beijing

app: insight-poc
service: insight-poc-function

functions:
hello_function:
name: insight-poc-hello-fn
code:
runtime: nodejs/v18
handler: index.handler
path: ./artifacts/function.zip
memory: 128
timeout: 30
environment:
NODE_ENV: production
34 changes: 34 additions & 0 deletions samples/volcengine-poc-vpc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
version: 0.1.0
provider:
name: volcengine
region: cn-beijing

app: insight-poc
service: insight-poc-vpc

functions:
vpc_function:
name: insight-poc-vpc-fn
code:
runtime: nodejs/v18
handler: index.handler
path: ./artifacts/function.zip
memory: 512
timeout: 60
network:
vpc_id: vpc-xxx
subnet_ids:
- subnet-xxx
security_group:
name: fn-security-group
ingress:
- protocol: TCP
port: 443
source: 0.0.0.0/0
egress:
- protocol: TCP
port: 0
destination: 0.0.0.0/0
environment:
DATABASE_URL: mysql://rds-host:3306/mydb
REDIS_URL: redis://redis-host:6379
29 changes: 26 additions & 3 deletions src/common/runtimeMapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,14 +153,37 @@ export const mapRuntime = (standardRuntime: string, provider: ProviderEnum): str
return providerRuntime;
};

export const isRuntimeSupported = (standardRuntime: string, provider: ProviderEnum): boolean => {
const mapping = runtimeMappings[standardRuntime as StandardRuntime];
const VOLCENGINE_NATIVE_RUNTIMES = [
'nodejs/v20',
'nodejs/v18',
'nodejs/v16',
'nodejs/v14',
'python/v3.12',
'python/v3.11',
'python/v3.10',
'python/v3.9',
'golang/v1',
'java/v21',
'java/v17',
'java/v11',
'java/v8',
];

export const isRuntimeSupported = (runtime: string, provider: ProviderEnum): boolean => {
if (provider === ProviderEnum.VOLCENGINE) {
return VOLCENGINE_NATIVE_RUNTIMES.includes(runtime);
}
const mapping = runtimeMappings[runtime as StandardRuntime];
return !!mapping && !!mapping[provider];
};

export const getSupportedRuntimes = (provider?: ProviderEnum): string[] => {
if (!provider) {
return Object.values(StandardRuntime);
return [...Object.values(StandardRuntime), ...VOLCENGINE_NATIVE_RUNTIMES];
}

if (provider === ProviderEnum.VOLCENGINE) {
return VOLCENGINE_NATIVE_RUNTIMES;
}

return Object.entries(runtimeMappings)
Expand Down
13 changes: 13 additions & 0 deletions src/validator/functionSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,19 @@ export const functionSchema = {
'php5.6',
'go1',
'dotnet_core3.1',
'nodejs/v20',
'nodejs/v18',
'nodejs/v16',
'nodejs/v14',
'python/v3.12',
'python/v3.11',
'python/v3.10',
'python/v3.9',
'golang/v1',
'java/v21',
'java/v17',
'java/v11',
'java/v8',
]),
handler: { type: 'string' },
path: { type: 'string' },
Expand Down
2 changes: 1 addition & 1 deletion src/validator/rootSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const rootSchema = {
provider: {
type: 'object',
properties: {
name: { type: 'string', enum: ['huawei', 'aliyun', 'tencent', 'aws'] },
name: { type: 'string', enum: ['huawei', 'aliyun', 'tencent', 'aws', 'volcengine'] },
region: { type: 'string' },
},
required: ['name', 'region'],
Expand Down
19 changes: 19 additions & 0 deletions tests/fixtures/serverless-insight-volcengine.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
version: 0.0.1
app: insight-poc-app
provider:
name: volcengine
region: cn-beijing

service: insight-poc

functions:
insight_poc_fn:
name: insight-poc-fn
code:
runtime: nodejs/v18
handler: index.handler
path: tests/fixtures/artifacts/artifact.zip
memory: 128
timeout: 30
environment:
NODE_ENV: production
169 changes: 169 additions & 0 deletions tests/service/mockCloudClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,175 @@ export const createMockTencentClient = (): MockTencentClient => ({
},
});

export type MockVolcengineClient = {
vefaas: {
createFunction: jest.Mock;
getFunction: jest.Mock;
updateFunctionConfiguration: jest.Mock;
updateFunctionCode: jest.Mock;
deleteFunction: jest.Mock;
listFunctions: jest.Mock;
};
tos: {
createBucket: jest.Mock;
getBucket: jest.Mock;
deleteBucket: jest.Mock;
updateBucketAcl: jest.Mock;
updateBucketWebsite: jest.Mock;
putObject: jest.Mock;
listObjects: jest.Mock;
deleteObjects: jest.Mock;
uploadFiles: jest.Mock;
};
iam: {
createRole: jest.Mock;
getRole: jest.Mock;
updateRoleTrustPolicy: jest.Mock;
deleteRole: jest.Mock;
attachRolePolicy: jest.Mock;
detachRolePolicy: jest.Mock;
};
tls: {
createProject: jest.Mock;
getProject: jest.Mock;
deleteProject: jest.Mock;
createTopic: jest.Mock;
getTopic: jest.Mock;
deleteTopic: jest.Mock;
createIndex: jest.Mock;
deleteIndex: jest.Mock;
waitForProject: jest.Mock;
waitForTopic: jest.Mock;
};
apigw: {
createGateway: jest.Mock;
getGateway: jest.Mock;
findGatewayByName: jest.Mock;
updateGateway: jest.Mock;
deleteGateway: jest.Mock;
createApi: jest.Mock;
getApi: jest.Mock;
updateApi: jest.Mock;
deleteApi: jest.Mock;
deployApi: jest.Mock;
bindDomain: jest.Mock;
unbindDomain: jest.Mock;
};
};

export const createMockVolcengineClient = (): MockVolcengineClient => ({
vefaas: {
createFunction: jest.fn().mockResolvedValue(undefined),
getFunction: jest.fn().mockResolvedValue({
functionId: 'func-123',
functionName: 'test-function',
runtime: 'nodejs/v18',
handler: 'index.handler',
memoryMb: 128,
requestTimeout: 30,
status: 'Active',
}),
updateFunctionConfiguration: jest.fn().mockResolvedValue(undefined),
updateFunctionCode: jest.fn().mockResolvedValue(undefined),
deleteFunction: jest.fn().mockResolvedValue(undefined),
listFunctions: jest.fn().mockResolvedValue([]),
},
tos: {
createBucket: jest.fn().mockResolvedValue({
name: 'test-bucket',
location: 'cn-beijing',
extranetEndpoint: 'test-bucket.tos-cn-beijing.volces.com',
}),
getBucket: jest.fn().mockResolvedValue({
name: 'test-bucket',
location: 'cn-beijing',
extranetEndpoint: 'test-bucket.tos-cn-beijing.volces.com',
}),
deleteBucket: jest.fn().mockResolvedValue(undefined),
updateBucketAcl: jest.fn().mockResolvedValue(undefined),
updateBucketWebsite: jest.fn().mockResolvedValue(undefined),
putObject: jest.fn().mockResolvedValue(undefined),
listObjects: jest.fn().mockResolvedValue([]),
deleteObjects: jest.fn().mockResolvedValue(undefined),
uploadFiles: jest.fn().mockResolvedValue(undefined),
},
iam: {
createRole: jest.fn().mockResolvedValue({
roleName: 'test-role',
roleId: 'role-123',
trn: 'trn:iam::123456789012:role/test-role',
}),
getRole: jest.fn().mockResolvedValue({
roleName: 'test-role',
roleId: 'role-123',
trn: 'trn:iam::123456789012:role/test-role',
}),
updateRoleTrustPolicy: jest.fn().mockResolvedValue(undefined),
deleteRole: jest.fn().mockResolvedValue(undefined),
attachRolePolicy: jest.fn().mockResolvedValue(undefined),
detachRolePolicy: jest.fn().mockResolvedValue(undefined),
},
tls: {
createProject: jest.fn().mockResolvedValue({
projectId: 'proj-123',
projectName: 'test-project',
status: 'Running',
}),
getProject: jest.fn().mockResolvedValue({
projectId: 'proj-123',
projectName: 'test-project',
status: 'Running',
}),
deleteProject: jest.fn().mockResolvedValue(undefined),
createTopic: jest.fn().mockResolvedValue({
topicId: 'topic-123',
topicName: 'test-topic',
status: 'Running',
}),
getTopic: jest.fn().mockResolvedValue({
topicId: 'topic-123',
topicName: 'test-topic',
status: 'Running',
}),
deleteTopic: jest.fn().mockResolvedValue(undefined),
createIndex: jest.fn().mockResolvedValue(undefined),
deleteIndex: jest.fn().mockResolvedValue(undefined),
waitForProject: jest.fn().mockResolvedValue(undefined),
waitForTopic: jest.fn().mockResolvedValue(undefined),
},
apigw: {
createGateway: jest.fn().mockResolvedValue({
gatewayId: 'gw-123',
gatewayName: 'test-gateway',
status: 'Running',
subDomain: 'gw-123.apig.cn-beijing.volces.com',
}),
getGateway: jest.fn().mockResolvedValue({
gatewayId: 'gw-123',
gatewayName: 'test-gateway',
status: 'Running',
subDomain: 'gw-123.apig.cn-beijing.volces.com',
}),
findGatewayByName: jest.fn().mockResolvedValue(null),
updateGateway: jest.fn().mockResolvedValue(undefined),
deleteGateway: jest.fn().mockResolvedValue(undefined),
createApi: jest.fn().mockResolvedValue('api-123'),
getApi: jest.fn().mockResolvedValue({
apiId: 'api-123',
apiName: 'test-api',
gatewayId: 'gw-123',
method: 'GET',
path: '/api/hello',
status: 'Running',
}),
updateApi: jest.fn().mockResolvedValue(undefined),
deleteApi: jest.fn().mockResolvedValue(undefined),
deployApi: jest.fn().mockResolvedValue(undefined),
bindDomain: jest.fn().mockResolvedValue(undefined),
unbindDomain: jest.fn().mockResolvedValue(undefined),
},
});

export const createMockContext = (overrides?: Partial<Context>): Context =>
({
provider: ProviderEnum.ALIYUN,
Expand Down
Loading
Loading