diff --git a/.vib/spring-cloud-dataflow/cypress/cypress/fixtures/applications.json b/.vib/spring-cloud-dataflow/cypress/cypress/fixtures/applications.json deleted file mode 100644 index 061cfe650..000000000 --- a/.vib/spring-cloud-dataflow/cypress/cypress/fixtures/applications.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "newApplication": { - "streamApplicationType": "Stream application starters for Kafka/Maven", - "taskApplicationType": "Task application starters for Maven", - "streamApplication1": "mongodb", - "streamApplication2": "cassandra" - } -} diff --git a/.vib/spring-cloud-dataflow/cypress/cypress/fixtures/imports.json b/.vib/spring-cloud-dataflow/cypress/cypress/fixtures/imports.json new file mode 100644 index 000000000..5a86e6097 --- /dev/null +++ b/.vib/spring-cloud-dataflow/cypress/cypress/fixtures/imports.json @@ -0,0 +1,4 @@ +{ + "taskStarters": "Task application starters for Docker", + "streamStarters": "Stream application starters for RabbitMQ/Docker" +} diff --git a/.vib/spring-cloud-dataflow/cypress/cypress/fixtures/schedules.json b/.vib/spring-cloud-dataflow/cypress/cypress/fixtures/schedules.json deleted file mode 100644 index bee6cc078..000000000 --- a/.vib/spring-cloud-dataflow/cypress/cypress/fixtures/schedules.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "newSchedule": { - "name": "test-schedule", - "cronExpression": "*/5 * * * *", - "taskType": "timestamp" - } -} diff --git a/.vib/spring-cloud-dataflow/cypress/cypress/fixtures/streams.json b/.vib/spring-cloud-dataflow/cypress/cypress/fixtures/streams.json index 5165ee0b4..9cf2bff54 100644 --- a/.vib/spring-cloud-dataflow/cypress/cypress/fixtures/streams.json +++ b/.vib/spring-cloud-dataflow/cypress/cypress/fixtures/streams.json @@ -1,6 +1,7 @@ { "newStream": { "name": "test-stream", - "type": "mongodb | cassandra" + "app1": "http", + "app2": "log" } } diff --git a/.vib/spring-cloud-dataflow/cypress/cypress/fixtures/task-to-import.json b/.vib/spring-cloud-dataflow/cypress/cypress/fixtures/task-to-import.json index e351f4414..bab38518c 100644 --- a/.vib/spring-cloud-dataflow/cypress/cypress/fixtures/task-to-import.json +++ b/.vib/spring-cloud-dataflow/cypress/cypress/fixtures/task-to-import.json @@ -2,7 +2,7 @@ "date": 1650360393208, "tasks": [ { - "name": "test-task-imported", + "name": "imported-task-rm3qg", "dslText": "timestamp", "composed": false, "status": "UNKNOWN", @@ -10,4 +10,4 @@ "description": "" } ] -} +} \ No newline at end of file diff --git a/.vib/spring-cloud-dataflow/cypress/cypress/fixtures/tasks.json b/.vib/spring-cloud-dataflow/cypress/cypress/fixtures/tasks.json deleted file mode 100644 index 5b2633be2..000000000 --- a/.vib/spring-cloud-dataflow/cypress/cypress/fixtures/tasks.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "newTask": { - "name": "test-task" - } -} diff --git a/.vib/spring-cloud-dataflow/cypress/cypress/integration/spring_cloud_dataflow_spec.js b/.vib/spring-cloud-dataflow/cypress/cypress/integration/spring_cloud_dataflow_spec.js index 2c908843e..d3b74a4c5 100644 --- a/.vib/spring-cloud-dataflow/cypress/cypress/integration/spring_cloud_dataflow_spec.js +++ b/.vib/spring-cloud-dataflow/cypress/cypress/integration/spring_cloud_dataflow_spec.js @@ -1,124 +1,52 @@ /// -import { random } from '../support/utils.js'; -import { - importAnApplication, - createATask, -} from '../support/prepare_app_state.js'; +import { random, importAppStarters } from '../support/utils.js'; -it('allows getting Spring Cloud Dataflow info', () => { - cy.visit('/dashboard'); - cy.get('.signpost-trigger').click(); - cy.get('.signpost-content-body') - .invoke('text') - .should('match', /.*[0-9].*/); - cy.contains('button', 'More info').click(); - cy.contains('.modal-content', 'Core') - .and('contain', 'Dashboard') - .and('contain', 'Shell'); +before(() => { + importAppStarters(); }); -it('allows a stream to be created and deployed', () => { - cy.fixture('applications').then((application) => { - importAnApplication(application.newApplication.streamApplicationType); - }); - cy.visit('dashboard/#/streams/list'); - cy.contains('button', 'Create stream(s)').click(); +it('allows creating a stream and deploying it', () => { + cy.visit('/dashboard/#/streams/list/create'); cy.fixture('streams').then((stream) => { - cy.get('.CodeMirror-line').type(stream.newStream.type); - }); - - cy.fixture('applications').then((application) => { - cy.contains('#v-2', application.newApplication.streamApplication1).and( - 'contain', - application.newApplication.streamApplication2 + cy.get('.CodeMirror-line').type( + `${stream.newStream.app1} | ${stream.newStream.app2}` ); - }); - - cy.contains('button', 'Create stream(s)').click(); - cy.get('.modal-content').should('contain', 'Create Stream'); - cy.fixture('streams').then((stream) => { + cy.contains('#v-2', stream.newStream.app1).and( + 'contain', + stream.newStream.app2 + ); + cy.contains('button', 'Create stream(s)').click(); + cy.get('.modal-content').should('contain', 'Create Stream'); cy.get('input[placeholder="Stream Name"]').type( `${stream.newStream.name}-${random}` ); - cy.contains('button', 'Create the stream').click(); - cy.contains( - '.datagrid-inner-wrapper', - `${stream.newStream.name}-${random}` + cy.contains('Create the stream').click(); + cy.contains('Stream(s) have been created successfully'); + + cy.visit( + `/dashboard/#/streams/list/${stream.newStream.name}-${random}/deploy` ); - cy.contains('.toast-container', 'successfully'); - cy.contains('clr-dg-cell', 'UNDEPLOYED') - .siblings('clr-dg-cell', stream.newStream.name) - .first() - .click(); + cy.contains('button', 'Deploy stream').click(); + cy.contains('Deploy success'); }); - - cy.contains('button#btn-deploy', 'Deploy stream').click(); - cy.contains('button', 'Deploy stream').click(); - cy.get('.toast-container').should('contain', 'Deploy success'); -}); - -it('allows a task to be scheduled and destroyed', () => { - cy.fixture('applications').then((application) => { - importAnApplication(application.newApplication.taskApplicationType); - }); - cy.fixture('schedules').then((schedule) => { - createATask(schedule.newSchedule.taskType); - }); - cy.visit('dashboard/#/tasks-jobs/tasks'); - cy.fixture('tasks').then((task) => { - cy.contains('clr-dg-cell', 'UNKNOWN') - .siblings('clr-dg-cell', task.newTask.name) - .first() - .click(); - }); - cy.contains('button', 'Schedule').click(); - cy.fixture('schedules').then((schedule) => { - cy.get('input[name="example"]') - .first() - .type(`${schedule.newSchedule.name}-${random}`); - - cy.get('input[name="example"]') - .last() - .type(`${schedule.newSchedule.cronExpression}`); - }); - - cy.contains('button', 'Create schedule(s)').click(); - cy.contains('.toast-container', 'Successfully'); - cy.contains('a', 'Tasks').click(); - cy.contains('clr-dg-cell', 'UNKNOWN') - .siblings('clr-dg-cell', 'test-task-') - .first() - .click(); - cy.contains('button', 'Destroy task').click(); - cy.contains('button', 'Destroy the task').click(); - cy.contains('1 task definition(s) destroyed.'); }); it('allows importing a task from a file and destroying it ', () => { cy.visit('/dashboard/#/manage/tools'); - cy.contains('a', 'Import tasks from a JSON file').click(); - cy.get('input[type="file"]').selectFile( - 'cypress/fixtures/task-to-import.json', - { force: true } - ); - cy.contains('button', 'Import').click(); - cy.contains('1 task(s) created'); - cy.get('.close').click(); - cy.visit('dashboard/#/tasks-jobs/tasks'); - cy.contains('button', 'Group Actions').click(); - cy.get('[aria-label="Select All"]').click({ force: true }); - cy.contains('button', 'Destroy task').click(); - cy.contains('.modal-content', 'Confirm Destroy Task'); - cy.contains('button', 'Destroy the task').click(); - cy.get('.toast-container').should('contain', 'destroyed'); -}); - -it('allows unregistering of an application', () => { - cy.fixture('applications').then((application) => { - importAnApplication(application.newApplication.streamApplicationType); + cy.contains('Import tasks').click(); + const newTask = 'cypress/fixtures/task-to-import.json'; + cy.readFile(newTask).then((obj) => { + obj.tasks.[0].name = `imported-task-${random}`; + cy.writeFile(newTask, obj); }); - cy.get('clr-dg-cell').siblings('clr-dg-cell', 'PROCESSOR').first().click(); - cy.contains('button', 'Unregister Application').click(); - cy.contains('button', 'Unregister the application').click(); - cy.contains('Successfully removed app'); + cy.get('[type="file"]').selectFile(newTask, { force: true }); + cy.contains('button', 'Import').click(); + cy.contains('task(s) created'); + + cy.visit('dashboard/#/tasks-jobs/tasks'); + cy.contains('Group Actions').click(); + cy.get('[aria-label="Select All"]').click({ force: true }); + cy.contains('Destroy task').click(); + cy.contains('Destroy the task').click(); + cy.contains('task definition(s) destroyed'); }); diff --git a/.vib/spring-cloud-dataflow/cypress/cypress/support/prepare_app_state.js b/.vib/spring-cloud-dataflow/cypress/cypress/support/prepare_app_state.js deleted file mode 100644 index 1b8f70d64..000000000 --- a/.vib/spring-cloud-dataflow/cypress/cypress/support/prepare_app_state.js +++ /dev/null @@ -1,26 +0,0 @@ -/// -import { random } from './utils'; - -export const importAnApplication = (application) => { - cy.visit('/dashboard'); - cy.contains('button', 'Add application(s)').click(); - cy.contains('label', application).click(); - cy.contains('.btn-primary', 'Import').click(); - cy.get('.toast-container').should('contain', 'Application(s) Imported'); -}; - -export const createATask = (taskType) => { - cy.visit('/dashboard/#/tasks-jobs/tasks'); - cy.contains('button', 'Create task').click(); - cy.get('.CodeMirror-line').type(taskType); - cy.contains('#v-2', taskType); - cy.contains('button', 'Create task').click(); - cy.contains('.modal-content', 'Create task'); - cy.fixture('tasks').then((task) => { - cy.get('input[placeholder="Task Name"]').type( - `${task.newTask.name}-${random}` - ); - cy.get('input#desc').type('This is a task'); - cy.contains('button', 'Create the task').click(); - }); -}; diff --git a/.vib/spring-cloud-dataflow/cypress/cypress/support/utils.js b/.vib/spring-cloud-dataflow/cypress/cypress/support/utils.js index 21de22ebf..5e9e3d316 100644 --- a/.vib/spring-cloud-dataflow/cypress/cypress/support/utils.js +++ b/.vib/spring-cloud-dataflow/cypress/cypress/support/utils.js @@ -1 +1,13 @@ export let random = (Math.random() + 1).toString(36).substring(7); + +export let importAppStarters = () => { + cy.visit('/dashboard'); + cy.fixture('imports').then((imports) => { + for(let [key, importType] of Object.entries(imports)) { + cy.contains('Add application').click(); + cy.contains('label', importType).click(); + cy.contains('Import Application(s)').click(); + cy.contains('Application(s) Imported'); + } + }); +}; diff --git a/.vib/spring-cloud-dataflow/goss/goss.yaml b/.vib/spring-cloud-dataflow/goss/goss.yaml index be85b3d8a..ad370d64c 100644 --- a/.vib/spring-cloud-dataflow/goss/goss.yaml +++ b/.vib/spring-cloud-dataflow/goss/goss.yaml @@ -1,22 +1,31 @@ +http: + http://spring-cloud-dataflow-skipper:{{ .Vars.skipper.service.port }}: + status: 200 file: /opt/bitnami/spring-cloud-dataflow/conf/application.yml: exists: true filetype: symlink mode: "0777" owner: root - /bitnami/spring-cloud-dataflow: + contains: + - {{ .Vars.server.configuration.accountName }} + - /runAsUser.*{{ .Vars.deployer.podSecurityContext.runAsUser }}/ + - /url.*jdbc:mariadb.*{{ .Vars.mariadb.auth.database }}/ + - /username.*{{ .Vars.mariadb.auth.username }}/ + /etc/secrets/database: exists: true filetype: directory - mode: "0775" + mode: "3777" + owner: root + /var/run/secrets/kubernetes.io/serviceaccount: + exists: {{ .Vars.serviceAccount.automountServiceAccountToken }} + filetype: directory + mode: "3777" owner: root command: - user-id-test: - exec: if [ "$(id -u)" -eq 0 ]; then exit 1; fi - exit-status: 0 - stdout: [] - stderr: [] - java-test: - exec: java -version + check-user-info: + exec: id exit-status: 0 stdout: - stderr: [] + - uid={{ .Vars.server.containerSecurityContext.runAsUser }} + - /groups=.*{{ .Vars.server.podSecurityContext.fsGroup }}/ diff --git a/.vib/spring-cloud-dataflow/goss/vars.yaml b/.vib/spring-cloud-dataflow/goss/vars.yaml new file mode 100644 index 000000000..48aeff76a --- /dev/null +++ b/.vib/spring-cloud-dataflow/goss/vars.yaml @@ -0,0 +1,19 @@ +server: + podSecurityContext: + fsGroup: 1002 + containerSecurityContext: + runAsUser: 1002 + configuration: + accountName: test_default +skipper: + service: + port: 80 +serviceAccount: + automountServiceAccountToken: true +deployer: + podSecurityContext: + runAsUser: 1002 +mariadb: + auth: + username: user_dataflow + database: test_dataflow diff --git a/.vib/spring-cloud-dataflow/vib-publish.json b/.vib/spring-cloud-dataflow/vib-publish.json index dfeab235f..3c30096e1 100644 --- a/.vib/spring-cloud-dataflow/vib-publish.json +++ b/.vib/spring-cloud-dataflow/vib-publish.json @@ -22,7 +22,7 @@ "url": "{SHA_ARCHIVE}", "path": "/bitnami/spring-cloud-dataflow" }, - "runtime_parameters": "c2VydmVyOgogIHNlcnZpY2U6CiAgICB0eXBlOiBMb2FkQmFsYW5jZXIKICAgIHBvcnQ6IDgwCg==", + "runtime_parameters": "c2VydmVyOgogIGNvbnRhaW5lclBvcnQ6IDgwODEKICBjb25maWd1cmF0aW9uOgogICAgYmF0Y2hFbmFibGVkOiB0cnVlCiAgICBhY2NvdW50TmFtZTogdGVzdF9kZWZhdWx0CiAgcG9kU2VjdXJpdHlDb250ZXh0OgogICAgZW5hYmxlZDogdHJ1ZQogICAgZnNHcm91cDogMTAwMgogIGNvbnRhaW5lclNlY3VyaXR5Q29udGV4dDoKICAgIGVuYWJsZWQ6IHRydWUKICAgIHJ1bkFzVXNlcjogMTAwMgogIHNlcnZpY2U6CiAgICB0eXBlOiBMb2FkQmFsYW5jZXIKICAgIHBvcnQ6IDgwCnNraXBwZXI6CiAgZW5hYmxlZDogdHJ1ZQogIHBvZFNlY3VyaXR5Q29udGV4dDoKICAgIGVuYWJsZWQ6IHRydWUKICAgIGZzR3JvdXA6IDEwMDIKICBjb250YWluZXJTZWN1cml0eUNvbnRleHQ6CiAgICBlbmFibGVkOiB0cnVlCiAgICBydW5Bc1VzZXI6IDEwMDIKICBzZXJ2aWNlOgogICAgdHlwZTogQ2x1c3RlcklQCiAgICBwb3J0OiA4MApkZXBsb3llcjoKICBwb2RTZWN1cml0eUNvbnRleHQ6CiAgICBlbmFibGVkOiB0cnVlCiAgICBydW5Bc1VzZXI6IDEwMDIKc2VydmljZUFjY291bnQ6CiAgY3JlYXRlOiB0cnVlCiAgYXV0b21vdW50U2VydmljZUFjY291bnRUb2tlbjogdHJ1ZQptYXJpYWRiOgogIGVuYWJsZWQ6IHRydWUKICBhdXRoOgogICAgdXNlcm5hbWU6IHVzZXJfZGF0YWZsb3cKICAgIHBhc3N3b3JkOiBDb21wbGljYXRlZFBhc3N3b3JkMTIzITQKICAgIGRhdGFiYXNlOiB0ZXN0X2RhdGFmbG93CiAgaW5pdGRiU2NyaXB0czoKICAgIGNyZWF0ZV9kYXRhYmFzZXMuc3FsOiB8CiAgICAgIENSRUFURSBPUiBSRVBMQUNFIFVTRVIgJ3NraXBwZXInQCclJyBpZGVudGlmaWVkIGJ5ICdDb21wbGljYXRlZFBhc3N3b3JkMTIzITQnOwogICAgICBDUkVBVEUgREFUQUJBU0UgSUYgTk9UIEVYSVNUUyBgc2tpcHBlcmA7CiAgICAgIEdSQU5UIEFMTCBPTiBza2lwcGVyLiogdG8gJ3NraXBwZXInQCclJzsKICAgICAgRkxVU0ggUFJJVklMRUdFUzs=", "target_platform": { "target_platform_id": "{VIB_ENV_TARGET_PLATFORM}", "size": { @@ -46,7 +46,8 @@ }, "remote": { "workload": "deploy-spring-cloud-dataflow-server" - } + }, + "vars_file": "vars.yaml" } }, { diff --git a/.vib/spring-cloud-dataflow/vib-verify.json b/.vib/spring-cloud-dataflow/vib-verify.json index dbcda9acc..46c3bb788 100644 --- a/.vib/spring-cloud-dataflow/vib-verify.json +++ b/.vib/spring-cloud-dataflow/vib-verify.json @@ -22,7 +22,7 @@ "url": "{SHA_ARCHIVE}", "path": "/bitnami/spring-cloud-dataflow" }, - "runtime_parameters": "c2VydmVyOgogIHNlcnZpY2U6CiAgICB0eXBlOiBMb2FkQmFsYW5jZXIKICAgIHBvcnQ6IDgwCg==", + "runtime_parameters": "c2VydmVyOgogIGNvbnRhaW5lclBvcnQ6IDgwODEKICBjb25maWd1cmF0aW9uOgogICAgYmF0Y2hFbmFibGVkOiB0cnVlCiAgICBhY2NvdW50TmFtZTogdGVzdF9kZWZhdWx0CiAgcG9kU2VjdXJpdHlDb250ZXh0OgogICAgZW5hYmxlZDogdHJ1ZQogICAgZnNHcm91cDogMTAwMgogIGNvbnRhaW5lclNlY3VyaXR5Q29udGV4dDoKICAgIGVuYWJsZWQ6IHRydWUKICAgIHJ1bkFzVXNlcjogMTAwMgogIHNlcnZpY2U6CiAgICB0eXBlOiBMb2FkQmFsYW5jZXIKICAgIHBvcnQ6IDgwCnNraXBwZXI6CiAgZW5hYmxlZDogdHJ1ZQogIHBvZFNlY3VyaXR5Q29udGV4dDoKICAgIGVuYWJsZWQ6IHRydWUKICAgIGZzR3JvdXA6IDEwMDIKICBjb250YWluZXJTZWN1cml0eUNvbnRleHQ6CiAgICBlbmFibGVkOiB0cnVlCiAgICBydW5Bc1VzZXI6IDEwMDIKICBzZXJ2aWNlOgogICAgdHlwZTogQ2x1c3RlcklQCiAgICBwb3J0OiA4MApkZXBsb3llcjoKICBwb2RTZWN1cml0eUNvbnRleHQ6CiAgICBlbmFibGVkOiB0cnVlCiAgICBydW5Bc1VzZXI6IDEwMDIKc2VydmljZUFjY291bnQ6CiAgY3JlYXRlOiB0cnVlCiAgYXV0b21vdW50U2VydmljZUFjY291bnRUb2tlbjogdHJ1ZQptYXJpYWRiOgogIGVuYWJsZWQ6IHRydWUKICBhdXRoOgogICAgdXNlcm5hbWU6IHVzZXJfZGF0YWZsb3cKICAgIHBhc3N3b3JkOiBDb21wbGljYXRlZFBhc3N3b3JkMTIzITQKICAgIGRhdGFiYXNlOiB0ZXN0X2RhdGFmbG93CiAgaW5pdGRiU2NyaXB0czoKICAgIGNyZWF0ZV9kYXRhYmFzZXMuc3FsOiB8CiAgICAgIENSRUFURSBPUiBSRVBMQUNFIFVTRVIgJ3NraXBwZXInQCclJyBpZGVudGlmaWVkIGJ5ICdDb21wbGljYXRlZFBhc3N3b3JkMTIzITQnOwogICAgICBDUkVBVEUgREFUQUJBU0UgSUYgTk9UIEVYSVNUUyBgc2tpcHBlcmA7CiAgICAgIEdSQU5UIEFMTCBPTiBza2lwcGVyLiogdG8gJ3NraXBwZXInQCclJzsKICAgICAgRkxVU0ggUFJJVklMRUdFUzs=", "target_platform": { "target_platform_id": "{VIB_ENV_TARGET_PLATFORM}", "size": { @@ -46,7 +46,8 @@ }, "remote": { "workload": "deploy-spring-cloud-dataflow-server" - } + }, + "vars_file": "vars.yaml" } }, {