Skip to content
This repository has been archived by the owner on Aug 16, 2024. It is now read-only.

Commit

Permalink
feat: add schema validation to the generator
Browse files Browse the repository at this point in the history
Signed-off-by: Valeriy Svydenko <[email protected]>
  • Loading branch information
svor committed Nov 14, 2023
1 parent e0bd29a commit cffc956
Show file tree
Hide file tree
Showing 30 changed files with 9,362 additions and 16 deletions.
2 changes: 1 addition & 1 deletion build/dockerfiles/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#
# SPDX-License-Identifier: EPL-2.0
#
FROM docker.io/node:16.13.0-alpine3.14 AS builder
FROM docker.io/node:18-alpine3.18 AS builder

ARG VERSION

Expand Down
2 changes: 1 addition & 1 deletion build/scripts/generate_devworkspace_templates.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ if [[ -z "$VERSION" || "$VERSION" == *"-next" ]]; then
VERSION="main"
fi

CHE_DEVWORKSPACE_GENERATOR_VERSION=0.0.1-99986b8
CHE_DEVWORKSPACE_GENERATOR_VERSION=next
PLUGIN_REGISTRY_URL=https://eclipse-che.github.io/che-plugin-registry/${VERSION}/v3

for dir in /build/devfiles/*/
Expand Down
1 change: 1 addition & 0 deletions tools/devworkspace-generator/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"homepage": "https://github.com/eclipse-che/che-devfile-registry#readme",
"dependencies": {
"@devfile/api": "latest",
"jsonschema": "^1.4.1",
"axios": "1.6.0",
"fs-extra": "^10.0.0",
"inversify": "^5.0.1",
Expand Down
10 changes: 10 additions & 0 deletions tools/devworkspace-generator/src/api/devfile-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,13 @@ export interface DevfileContext {
// suffix to append on generated names
suffix: string;
}

/**
* Enum for Devfile schema versions
*/
export enum DevfileSchemaVersion {
V200 = '2.0.0',
V210 = '2.1.0',
V220 = '2.2.0',
V221_alpha = '2.2.1-alpha',
}
2,852 changes: 2,852 additions & 0 deletions tools/devworkspace-generator/src/devfile-schema/2.0.0/devfile.json

Large diffs are not rendered by default.

1,430 changes: 1,430 additions & 0 deletions tools/devworkspace-generator/src/devfile-schema/2.1.0/devfile.json

Large diffs are not rendered by default.

2,037 changes: 2,037 additions & 0 deletions tools/devworkspace-generator/src/devfile-schema/2.2.0/devfile.json

Large diffs are not rendered by default.

2,037 changes: 2,037 additions & 0 deletions tools/devworkspace-generator/src/devfile-schema/2.2.1-alpha/devfile.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**********************************************************************
* Copyright (c) 2023 Red Hat, Inc.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
***********************************************************************/
import { ContainerModule, interfaces } from 'inversify';

import { DevfileSchemaValidator } from './devfile-schema-validator';

const devfileSchemaModule = new ContainerModule((bind: interfaces.Bind) => {
bind(DevfileSchemaValidator).toSelf().inSingletonScope();
});

export { devfileSchemaModule };
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**********************************************************************
* Copyright (c) 2023 Red Hat, Inc.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
***********************************************************************/
import { injectable } from 'inversify';

import * as devfileSchemaV200 from './2.0.0/devfile.json';
import * as devfileSchemaV210 from './2.1.0/devfile.json';
import * as devfileSchemaV220 from './2.2.0/devfile.json';
import * as devfileSchemaV221Alpha from './2.2.1-alpha/devfile.json';
import * as Validator from 'jsonschema';
import { DevfileSchemaVersion } from '../api/devfile-context';

@injectable()
export class DevfileSchemaValidator {
getDevfileSchema(version: string) {
switch (version) {
case DevfileSchemaVersion.V200:
return devfileSchemaV200;
case DevfileSchemaVersion.V210:
return devfileSchemaV210;
case DevfileSchemaVersion.V220:
return devfileSchemaV220;
case DevfileSchemaVersion.V221_alpha:
return devfileSchemaV221Alpha;
default:
throw new Error(`Dev Workspace generator tool doesn't support devfile version: ${version}`);
}
}

// Validates devfile against schema
validateDevfile(devfile: any, version: string) {
const schema = this.getDevfileSchema(version);
const validatorResult = Validator.validate(devfile, schema, { nestedErrors: true });

return validatorResult;
}
}
3 changes: 1 addition & 2 deletions tools/devworkspace-generator/src/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export class Generate {
await fs.writeFile(outputFile, generatedContent, 'utf-8');
}

console.log(`DevWorkspace ${context.devWorkspaceTemplates[0].metadata.name} was generated.`);
console.log(`DevWorkspace ${context.devWorkspaceTemplates[0].metadata.name} was generated`);
return context;
}

Expand All @@ -71,7 +71,6 @@ export class Generate {
): Promise<DevfileContext> {
const devfile = jsYaml.load(devfileContent);

// const originalDevfile = Object.assign({}, devfile);
// sets the suffix to the devfile name
const suffix = devfile.metadata.name || '';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { fetchModule } from '../fetch/fetch-module';
import { githubModule } from '../github/github-module';
import { resolveModule } from '../resolve/resolve-module';
import { pluginRegistryModule } from '../plugin-registry/plugin-registry-module';
import { devfileSchemaModule } from '../devfile-schema/devfile-schema-module';
import { bitbucketModule } from '../bitbucket/bitbucket-module';
import { bitbucketServerModule } from '../bitbucket-server/bitbucket-server-module';

Expand All @@ -35,6 +36,7 @@ export class InversifyBinding {
this.container.load(bitbucketServerModule);
this.container.load(resolveModule);
this.container.load(pluginRegistryModule);
this.container.load(devfileSchemaModule);

this.container.bind(Symbol.for('AxiosInstance')).toConstantValue(options.axiosInstance);
this.container.bind('string').toConstantValue(options.pluginRegistryUrl).whenTargetNamed('PLUGIN_REGISTRY_URL');
Expand Down
20 changes: 20 additions & 0 deletions tools/devworkspace-generator/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@
import * as axios from 'axios';
import * as fs from 'fs-extra';
import { Generate } from './generate';
import { DevfileSchemaValidator } from './devfile-schema/devfile-schema-validator';
import * as jsYaml from 'js-yaml';
import { InversifyBinding } from './inversify/inversify-binding';
import { UrlFetcher } from './fetch/url-fetcher';
import { PluginRegistryResolver } from './plugin-registry/plugin-registry-resolver';
import { V1alpha2DevWorkspaceSpecTemplate } from '@devfile/api';
import { DevfileContext } from './api/devfile-context';
import { GitUrlResolver } from './resolve/git-url-resolver';
import { ValidatorResult } from 'jsonschema';

export class Main {
/**
Expand Down Expand Up @@ -100,6 +102,24 @@ export class Main {
devfileContent = params.devfileContent;
}

const jsYamlDevfileContent = jsYaml.load(devfileContent);
const schemaVersion = jsYamlDevfileContent.schemaVersion;
if (!schemaVersion) {
throw new Error(`Devfile is not valid, schemaVersion is required`);
}

// validate devfile
const devfileSchemaValidator = container.get(DevfileSchemaValidator);
console.log(`Validating devfile`);
const validationResult: ValidatorResult = devfileSchemaValidator.validateDevfile(
jsYamlDevfileContent,
schemaVersion
);
if (!validationResult.valid) {
throw new Error(`Devfile schema validation failed. Error: ${validationResult.toString()}`);
}
console.log(`Devfile is valid with schema version ${schemaVersion}`);

// enhance projects
devfileContent = this.replaceIfExistingProjects(devfileContent, params.projects);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
schemaVersion: 2.0.0
metadata:
name: ansible-demo
namespace: svor-che
projects:
- name: ansible-devspaces-demo
git:
remotes:
origin: https://github.com/svor/ansible-devspaces-demo.git
checkoutFrom:
revision: sv-test-pr-with-new-ee-image
components:
- name: tooling-container
container:
image: quay.io/vsvydenk/ansible-creator-ee:base20
memoryLimit: 6Gi
args:
- tail
- '-f'
- /dev/null
commands:
- id: oc-install
exec:
commandLine: /usr/local/bin/ansible-playbook ${PROJECT_SOURCE}/playbooks/install_oc.yml
workingDir: ${PROJECT_SOURCE}
group:
kind: build
isDefault: true
component: tooling-container
- id: molecule-test
exec:
label: 'Molecule: Run Scenario for Backup Role'
commandLine: source $HOME/.bashrc && molecule test
workingDir: ${PROJECTS_ROOT}/ansible-devspaces-demo/collections/example/collection/roles/backup_file
group:
kind: run
isDefault: true
component: tooling-container
- id: molecule-verify
exec:
label: 'Molecule: Validate Backup File Role'
commandLine: source $HOME/.bashrc && molecule verify
workingDir: ${PROJECTS_ROOT}/ansible-devspaces-demo/collections/example/collection/roles/backup_file
group:
kind: run
isDefault: true
component: tooling-container
events:
postStart:
- oc-install
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
schemaVersion: 2.0.0
metadata:
name: empty
namespace: svor-che
components:
- name: universal-developer-image
container:
image: quay.io/devfile/universal-developer-image:ubi8-latest
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
schemaVersion: 2.0.0
metadata:
generateName: quarkus-api-example
components:
- name: tools
container:
image: quay.io/devfile/universal-developer-image:ubi8-latest
env:
- name: QUARKUS_HTTP_HOST
value: 0.0.0.0
endpoints:
- exposure: none
name: debug
protocol: tcp
targetPort: 5005
- exposure: public
name: list-all-food
protocol: http
targetPort: 8080
path: /food
volumeMounts:
- name: m2
path: /home/user/.m2
memoryLimit: 6G
mountSources: true

- name: postgresql
container:
image: 'quay.io/centos7/postgresql-13-centos7@sha256:994f5c622e2913bda1c4a7fa3b0c7e7f75e7caa3ac66ff1ed70ccfe65c40dd75'
env:
- name: POSTGRESQL_USER
value: user
- name: POSTGRESQL_PASSWORD
value: password
- name: POSTGRESQL_DATABASE
value: food_db
- name: PGDATA
value: /tmp/pgdata
- name: m2
volume:
size: 1G
commands:
- id: package
exec:
label: "Package"
component: tools
workingDir: ${PROJECTS_ROOT}/quarkus-api-example
commandLine: "./mvnw clean package -DskipTests=true"
group:
kind: build
isDefault: true
- id: runtests
exec:
label: "Run Tests"
component: tools
workingDir: ${PROJECTS_ROOT}/quarkus-api-example
commandLine: "./mvnw test"
group:
kind: test
- id: packagenative
exec:
label: "Package Native"
component: tools
workingDir: ${PROJECTS_ROOT}/quarkus-api-example
commandLine: "./mvnw package -Dnative -Dmaven.test.skip -Dquarkus.native.native-image-xmx=3G"
group:
kind: build
- id: startdev
exec:
label: "Start Development mode (Hot reload + debug)"
component: tools
workingDir: ${PROJECTS_ROOT}/quarkus-api-example
commandLine: "./mvnw compile quarkus:dev"
group:
kind: run
isDefault: true
- id: startnative
exec:
label: "Start Native"
component: tools
workingDir: ${PROJECTS_ROOT}/quarkus-api-example/target
commandLine: "./quarkus-api-example-1.0.0-SNAPSHOT-runner"
group:
kind: run
- id: buildimage
exec:
label: "Build Image"
component: tools
workingDir: ${PROJECT_SOURCE}
commandLine: "podman build -f src/main/docker/Dockerfile.jvm -t quay.io/che-incubator/quarkus-api-example ."
group:
kind: build
- id: deploypostgres
exec:
label: "Deploy Postrgres"
component: tools
workingDir: ${PROJECTS_ROOT}/quarkus-api-example
commandLine: "oc new-app -e POSTGRESQL_USER=user -e POSTGRESQL_PASSWORD=password -e POSTGRESQL_DATABASE=food_db postgresql:10-el7 -n demo"
group:
kind: test
events:
postStart:
- package
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
schemaVersion: 2.1.0
metadata:
name: ansible-demo
namespace: svor-che
projects:
- name: ansible-devspaces-demo
git:
remotes:
origin: https://github.com/svor/ansible-devspaces-demo.git
checkoutFrom:
revision: sv-test-pr-with-new-ee-image
components:
- name: tooling-container
container:
image: quay.io/vsvydenk/ansible-creator-ee:base20
memoryRequest: 256M
memoryLimit: 6Gi
cpuRequest: 250m
cpuLimit: 2000m
args:
- tail
- '-f'
- /dev/null
commands:
- id: oc-install
exec:
commandLine: /usr/local/bin/ansible-playbook ${PROJECT_SOURCE}/playbooks/install_oc.yml
workingDir: ${PROJECT_SOURCE}
group:
kind: build
isDefault: true
component: tooling-container
- id: molecule-test
exec:
label: 'Molecule: Run Scenario for Backup Role'
commandLine: source $HOME/.bashrc && molecule test
workingDir: ${PROJECTS_ROOT}/ansible-devspaces-demo/collections/example/collection/roles/backup_file
group:
kind: run
isDefault: true
component: tooling-container
- id: molecule-verify
exec:
label: 'Molecule: Validate Backup File Role'
commandLine: source $HOME/.bashrc && molecule verify
workingDir: ${PROJECTS_ROOT}/ansible-devspaces-demo/collections/example/collection/roles/backup_file
group:
kind: run
isDefault: true
component: tooling-container
events:
postStart:
- oc-install
Loading

0 comments on commit cffc956

Please sign in to comment.