diff --git a/create-database.yml b/create-database.yml new file mode 100644 index 0000000..d10afc3 --- /dev/null +++ b/create-database.yml @@ -0,0 +1,86 @@ +--- + +############################################################# +# Creating inventory dynamically for given parameters +############################################################# + +- hosts: localhost + connection: local + gather_facts: false + + pre_tasks: + - name: "Check if ansible version is at least 2.10.x" + assert: + that: + - ansible_version.major >= 2 + - ansible_version.minor >= 10 + msg: "The ansible version has to be at least ({{ ansible_version.full }})" + + tasks: + - name: Add hosts + add_host: + name: "{{ stage }}-{{ cluster_name }}-{{ '%02d' | format(item|int) }}" + groups: + - "stage_{{ stage }}" + - "{{ cluster_service }}" + with_sequence: start=1 end={{ cluster_size | default(1) }} + +############################################################# +# Setup databases for created inventory +############################################################# + +- hosts: "stage_{{ stage }}" + serial: "{{ serial_number | default(5) }}" + remote_user: root + + pre_tasks: + - name: "Gather current server infos" + hcloud_server_info: + api_token: "{{ hetzner_authentication_token }}" + register: hetzner_server_infos + delegate_to: 127.0.0.1 + become: false + + - name: "Set current server infos as fact: hetzner_server_infos_json" + set_fact: + hetzner_server_infos_json: "{{ hetzner_server_infos.hcloud_server_info }}" + delegate_to: 127.0.0.1 + become: false + + - name: "Read ip address for {{ inventory_hostname }}" + set_fact: + stage_server_ip: "{{ item.ipv4_address }}" + when: item.name == inventory_hostname + with_items: "{{ hetzner_server_infos_json }}" + delegate_to: 127.0.0.1 + become: false + +# - name: Print the gathered infos +# debug: +# var: stage_server_ip +# delegate_to: 127.0.0.1 + + roles: + - role: connect-postgres + +############################################################# +# Sending smardigo management message to process +############################################################# + +- hosts: "stage_{{ stage }}" + serial: "{{ serial_number | default(5) }}" + connection: local + gather_facts: false + + post_tasks: + - name: "Sending smardigo management message <{{ smardigo_management_action }}> to <{{ scope_id }}/{{ process_instance_id }}>" + uri: + url: "{{ smardigo_management_url }}" + method: POST + body_format: json + body: "{{ lookup('template','smardigo-management-message.json.j2') }}" + headers: + accept: "*/*" + Content-Type: "application/json" + Smardigo-User-Token: "{{ smardigo_management_token }}" + status_code: [200] diff --git a/create-realm.yml b/create-realm.yml new file mode 100644 index 0000000..d345abf --- /dev/null +++ b/create-realm.yml @@ -0,0 +1,84 @@ +--- + +############################################################# +# Creating inventory dynamically for given parameters +############################################################# + +- hosts: localhost + connection: local + gather_facts: false + + pre_tasks: + - name: "Check if ansible version is at least 2.10.x" + assert: + that: + - ansible_version.major >= 2 + - ansible_version.minor >= 10 + msg: "The ansible version has to be at least ({{ ansible_version.full }})" + + tasks: + - name: Add hosts + add_host: + name: "{{ stage }}-{{ cluster_name }}-{{ '%02d' | format(item|int) }}" + groups: + - "stage_{{ stage }}" + - "{{ cluster_service }}" + with_sequence: start=1 end={{ cluster_size | default(1) }} + +############################################################# +# Setup realms for created inventory +############################################################# + +- hosts: "stage_{{ stage }}" + serial: "{{ serial_number | default(5) }}" + become: false + gather_facts: false + + pre_tasks: + - name: "Gather current server infos" + hcloud_server_info: + api_token: "{{ hetzner_authentication_token }}" + register: hetzner_server_infos + delegate_to: 127.0.0.1 + + - name: "Set current server infos as fact: hetzner_server_infos_json" + set_fact: + hetzner_server_infos_json: "{{ hetzner_server_infos.hcloud_server_info }}" + delegate_to: 127.0.0.1 + + - name: "Read ip address for {{ inventory_hostname }}" + set_fact: + stage_server_ip: "{{ item.ipv4_address }}" + when: item.name == inventory_hostname + with_items: "{{ hetzner_server_infos_json }}" + delegate_to: 127.0.0.1 + + - name: Print the gathered infos + debug: + var: stage_server_ip + delegate_to: 127.0.0.1 + + roles: + - role: connect-realm + +############################################################# +# Sending smardigo management message to process +############################################################# + +- hosts: "stage_{{ stage }}" + serial: "{{ serial_number | default(5) }}" + connection: local + gather_facts: false + + post_tasks: + - name: "Sending smardigo management message <{{ smardigo_management_action }}> to <{{ scope_id }}/{{ process_instance_id }}>" + uri: + url: "{{ smardigo_management_url }}" + method: POST + body_format: json + body: "{{ lookup('template','smardigo-management-message.json.j2') }}" + headers: + accept: "*/*" + Content-Type: "application/json" + Smardigo-User-Token: "{{ smardigo_management_token }}" + status_code: [200] diff --git a/create-server.yml b/create-server.yml new file mode 100644 index 0000000..006ece4 --- /dev/null +++ b/create-server.yml @@ -0,0 +1,161 @@ +--- + +############################################################# +# Creating inventory dynamically for given parameters +############################################################# + +- hosts: localhost + connection: local + gather_facts: false + + pre_tasks: + - name: "Check if ansible version is at least 2.10.x" + assert: + that: + - ansible_version.major >= 2 + - ansible_version.minor >= 10 + msg: "The ansible version has to be at least ({{ ansible_version.full }})" + + tasks: + - name: Add hosts + add_host: + name: "{{ stage }}-{{ cluster_name }}-{{ '%02d' | format(item|int) }}" + groups: + - "stage_{{ stage }}" + - "{{ cluster_service }}" + with_sequence: start=1 end={{ cluster_size | default(1) }} + +############################################################# +# Provisioning servers for created inventory +############################################################# + +- hosts: "stage_{{ stage }}" + serial: "{{ serial_number | default(5) }}" + gather_facts: false + + pre_tasks: + - name: Get all Firewalls from Hetzner + uri: + url: "https://api.hetzner.cloud/v1/firewalls" + headers: + accept: application/json + authorization: Bearer {{ hetzner_authentication_token }} + return_content: yes + register: hetzner_firewalls_response + delegate_to: 127.0.0.1 + tags: + - update_networks + + - name: Save firewall entries as variable (fact) + set_fact: + hetzner_firewalls_response_json: "{{ hetzner_firewalls_response.json }}" + tags: + - update_networks + + - name: Parse firewall entries + set_fact: + firewall_records: "{{ hetzner_firewalls_response_json.firewalls | json_query(jmesquery) }}" + vars: + jmesquery: '[*].{id: id, name: name}' + tags: + - update_networks + + - name: Print firewall entries + debug: + msg: "{{ firewall_records }}" + tags: + - update_networks + + roles: + - role: hcloud + +############################################################# +# Setup servers for created inventory +############################################################# + +- hosts: "stage_{{ stage }}" + serial: "{{ serial_number | default(5) }}" + remote_user: root + + pre_tasks: + - name: Remove outdated dependencies + apt: + name: [ + 'docker', + 'docker-client', + 'docker-client-latest', + 'docker-common', + 'docker-latest', + 'docker-latest-logrotate', + 'docker-logrotate', + 'docker-engine', + 'smartmontools', + ] + state: 'absent' + when: ansible_distribution == "Ubuntu" + + - name: "Gather current server infos" + hcloud_server_info: + api_token: "{{ hetzner_authentication_token }}" + register: hetzner_server_infos + delegate_to: 127.0.0.1 + become: false + + - name: "Set current server infos as fact: hetzner_server_infos_json" + set_fact: + hetzner_server_infos_json: "{{ hetzner_server_infos.hcloud_server_info }}" + delegate_to: 127.0.0.1 + become: false + + - name: "Read ip address for {{ inventory_hostname }}" + set_fact: + stage_server_ip: "{{ item.ipv4_address }}" + when: item.name == inventory_hostname + with_items: "{{ hetzner_server_infos_json }}" + delegate_to: 127.0.0.1 + become: false + +# - name: Print the gathered infos +# debug: +# var: stage_server_ip +# delegate_to: 127.0.0.1 + + roles: + - role: ansible-role-docker + vars: + docker_compose_version: '1.29.1' + docker_compose_path: '/usr/bin/docker-compose' + docker_users: '{{ smardigo_plattform_users }}' + + - role: common + + - role: filebeat + when: filebeat_enabled | default(True) + + - role: node-exporter + when: node_exporter_enabled | default(True) + + - role: traefik + when: traefik_enabled | default(True) + +############################################################# +# Sending smardigo management message to process +############################################################# + +- hosts: "stage_{{ stage }}" + serial: "{{ serial_number | default(5) }}" + connection: local + gather_facts: false + + post_tasks: + - name: "Sending smardigo management message <{{ smardigo_management_action }}> to <{{ scope_id }}/{{ process_instance_id }}>" + uri: + url: "{{ smardigo_management_url }}" + method: POST + body_format: json + body: "{{ lookup('template','smardigo-management-message.json.j2') }}" + headers: + accept: "*/*" + Content-Type: "application/json" + Smardigo-User-Token: "{{ smardigo_management_token }}" + status_code: [200] diff --git a/create-service.yml b/create-service.yml new file mode 100644 index 0000000..0d823f7 --- /dev/null +++ b/create-service.yml @@ -0,0 +1,83 @@ +--- + +############################################################# +# Creating inventory dynamically for given parameters +############################################################# + +- hosts: localhost + connection: local + gather_facts: false + + pre_tasks: + - name: "Check if ansible version is at least 2.10.x" + assert: + that: + - ansible_version.major >= 2 + - ansible_version.minor >= 10 + msg: "The ansible version has to be at least ({{ ansible_version.full }})" + + tasks: + - name: Add hosts + add_host: + name: "{{ stage }}-{{ cluster_name }}-{{ '%02d' | format(item|int) }}" + groups: + - "stage_{{ stage }}" + - "{{ cluster_service }}" + with_sequence: start=1 end={{ cluster_count | default(1) }} + +############################################################# +# Setup services for created inventory +############################################################# + +- hosts: "stage_{{ stage }}" + serial: "{{ serial_number | default(5) }}" + remote_user: root + + pre_tasks: + - name: "Gather current server infos" + hcloud_server_info: + api_token: "{{ hetzner_authentication_token }}" + register: hetzner_server_infos + delegate_to: 127.0.0.1 + + - name: "Set current server infos as fact: hetzner_server_infos_json" + set_fact: + hetzner_server_infos_json: "{{ hetzner_server_infos.hcloud_server_info }}" + delegate_to: 127.0.0.1 + + - name: "Read ip address for {{ inventory_hostname }}" + set_fact: + stage_server_ip: "{{ item.ipv4_address }}" + when: item.name == inventory_hostname + with_items: "{{ hetzner_server_infos_json }}" + delegate_to: 127.0.0.1 + + - name: Print the gathered infos + debug: + var: stage_server_ip + delegate_to: 127.0.0.1 + + roles: + - role: connect + +############################################################# +# run provisioning against newly created inventory +############################################################# + +- hosts: "stage_{{ stage }}" + serial: "{{ serial_number | default(5) }}" + connection: local + gather_facts: false + + post_tasks: + - name: "Sending smardigo management message <{{ smardigo_management_action }}> to <{{ scope_id }}/{{ process_instance_id }}>" + uri: + url: "{{ smardigo_management_url }}" + method: POST + body_format: json + body: "{{ lookup('template','smardigo-management-message.json.j2') }}" + headers: + accept: "*/*" + Content-Type: "application/json" + Smardigo-User-Token: "{{ smardigo_management_token }}" + status_code: [200] diff --git a/group_vars/connect/plain.yml b/group_vars/connect/plain.yml new file mode 100644 index 0000000..b603e7a --- /dev/null +++ b/group_vars/connect/plain.yml @@ -0,0 +1,34 @@ +--- + +service: "connect" + +hetzner_server_type: cx21 +hetzner_server_labels: "stage={{ stage }} service={{ service }}" + +connect_jwt_enabled: true +connect_jwt_secret: 908ae14462d049d3be84964ef379c7c6 + +connect_postgres_database: "connect-postgres" +connect_postgres_admin_username: "connect-postgres-admin" +connect_postgres_admin_password: "connect-postgres-admin" + +current_realm_clients: [ + { + clientId: 'connect', + name: 'connect', + admin_url: '', + root_url: '', + redirect_uris: ' + [ + "https://{{ service_name }}.{{ domain }}/*", + ]', + secret: '{{ cluster_name }}', + web_origins: ' + [ + "https://{{ service_name }}.{{ domain }}/*", + ]', + } +] + +#connect_csrf_token_name: "< see vault >" +#connect_csrf_token_value: "< see vault >" diff --git a/group_vars/connect/play.yml b/group_vars/connect/play.yml deleted file mode 100644 index b1fcff8..0000000 --- a/group_vars/connect/play.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- - -service: "connect" - -connect_jwt_enabled: true -connect_jwt_secret: 908ae14462d049d3be84964ef379c7c6 - -#connect_csrf_token_name: "< see vault >" -#connect_csrf_token_value: "< see vault >" diff --git a/group_vars/dynamic_connect.yml b/group_vars/dynamic_connect.yml deleted file mode 100644 index 50f8c78..0000000 --- a/group_vars/dynamic_connect.yml +++ /dev/null @@ -1,16 +0,0 @@ ---- - -hetzner_server_type: cx21 -hetzner_server_labels: "stage={{ stage }} service={{ service }}" - -# TODO create realm/client for tenant and service -connect_auth_module: oidc -connect_oidc_client_id: connect-01 -connect_oidc_client_secret: 9e234965-1041-4653-8a0e-db964c04bc26 -connect_oidc_registration_id: connect-01 -connect_oidc_issuer_uri: https://{{ keycloak_hostname }}/auth/realms/smardigo-01 -connect_password_change_url: https://{{ keycloak_hostname }}/auth/realms/smardigo-01/account/password -connect_iam_user_management_url: https://{{ keycloak_hostname }}/auth/admin/smardigo-01/console - -spring_profiles_include_suffix: ",{{ inventory_hostname }}" -ribbon_display_on_active_profiles: "{{ inventory_hostname }}" diff --git a/group_vars/stage_dev/plain.yml b/group_vars/stage_dev/plain.yml index 8dd794e..6e55380 100644 --- a/group_vars/stage_dev/plain.yml +++ b/group_vars/stage_dev/plain.yml @@ -2,6 +2,8 @@ stage: "dev" +keycloak_server_url: "https://dev-keycloak-01.smardigo.digital" + docker_registry: dev-docker-registry-01.smardigo.digital docker_registry_username: "< see vault >" docker_registry_token: "< see vault >" @@ -81,4 +83,7 @@ keycloak_extra_hosts: [ hostname: "{{ mail_hostname }}", ip: 10.2.0.2, } -] \ No newline at end of file +] + +smardigo_management_url: "http://localhost:8080/api/v1/scopes/{{ scope_id }}/processes/{{ process_instance_id }}/messages" +smardigo_management_token: "eyJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiYWxnIjoiZGlyIn0..xiS4DrBqSprqYdR94ACbUw.OHRxU9nmP25JiGlJMyw9XaSB2Q3GZ4yiG7I7UZlbv9k.q5I2KulPbvhN5yO08bGqfw" \ No newline at end of file diff --git a/host_vars/dev-keycloak-01.yml b/host_vars/dev-keycloak-01.yml index 0b4d49b..460324a 100644 --- a/host_vars/dev-keycloak-01.yml +++ b/host_vars/dev-keycloak-01.yml @@ -2,6 +2,8 @@ hetzner_server_labels: "stage={{ stage }} service=keycloak" +keycloak_server_url: "http://localhost:{{ service_port_keycloak_external }}" + keycloak: { realms: [ { @@ -69,66 +71,6 @@ keycloak: { ]', } ] - }, - { - name: 'smardigo-01', - display_name: 'smardigo-01', - users: [ - { - "username": "connect-admin", - "password": "connect-admin", - } - ], - clients: [ - { - clientId: 'connect-01', - name: 'connect-01', - admin_url: '', - root_url: '', - redirect_uris: ' - [ - "https://dev-connect-01.smardigo.digital/*", - "http://dev-connect-01.smardigo.digital/*", - ]', - secret: '9e234965-1041-4653-8a0e-db964c04bc26', - web_origins: ' - [ - "https://dev-connect-01.smardigo.digital", - ]', - }, - { - clientId: 'connect-02', - name: 'connect-02', - admin_url: '', - root_url: '', - redirect_uris: ' - [ - "https://dev-connect-02.smardigo.digital/*", - "http://dev-connect-02.smardigo.digital/*", - ]', - secret: '9e234965-1041-4653-8a0e-db964c04bc26', - web_origins: ' - [ - "https://dev-connect-02.smardigo.digital", - ]', - }, - { - clientId: 'connect-03', - name: 'connect-03', - admin_url: '', - root_url: '', - redirect_uris: ' - [ - "https://dev-connect-03.smardigo.digital/*", - "http://dev-connect-03.smardigo.digital/*", - ]', - secret: '9e234965-1041-4653-8a0e-db964c04bc26', - web_origins: ' - [ - "https://dev-connect-03.smardigo.digital", - ]', - }, - ] - }, + } ] } \ No newline at end of file diff --git a/roles/connect-postgres/defaults/main.yml b/roles/connect-postgres/defaults/main.yml new file mode 100644 index 0000000..c852850 --- /dev/null +++ b/roles/connect-postgres/defaults/main.yml @@ -0,0 +1,5 @@ +--- + +connect_postgres_service_name: "{{ service_name }}-connectpostgres" + +connect_postgres_version: "12" diff --git a/roles/connect-postgres/handlers/main.yml b/roles/connect-postgres/handlers/main.yml new file mode 100644 index 0000000..ed97d53 --- /dev/null +++ b/roles/connect-postgres/handlers/main.yml @@ -0,0 +1 @@ +--- diff --git a/roles/connect-postgres/meta/main.yml b/roles/connect-postgres/meta/main.yml new file mode 100644 index 0000000..ed97d53 --- /dev/null +++ b/roles/connect-postgres/meta/main.yml @@ -0,0 +1 @@ +--- diff --git a/roles/connect-postgres/tasks/main.yml b/roles/connect-postgres/tasks/main.yml new file mode 100644 index 0000000..cd7a658 --- /dev/null +++ b/roles/connect-postgres/tasks/main.yml @@ -0,0 +1,83 @@ +--- + +### tags: +### update_deployment + +- name: "Send mattermost message" + uri: + url: "{{ mattermost_hook_smardigo }}" + method: POST + body: "{{ lookup('template','mattermost-deploy-start.json.j2') }}" + body_format: json + headers: + Content-Type: "application/json" + delegate_to: 127.0.0.1 + become: false + when: + - send_status_messages + +- name: "Check if {{ connect_postgres_service_name }}/docker-compose.yml exists" + stat: + path: '{{ service_base_path }}/{{ connect_postgres_service_name }}/docker-compose.yml' + register: check_docker_compose_file + tags: + - update_deployment + +- name: "Stop {{ connect_postgres_service_name }}" + shell: docker-compose down + args: + chdir: '{{ service_base_path }}/{{ connect_postgres_service_name }}' + when: check_docker_compose_file.stat.exists + ignore_errors: yes + tags: + - update_deployment + +- name: "Deploy docker templates for {{ connect_postgres_service_name }}" + include_role: + name: _deploy + tasks_from: templates + vars: + current_config: "_docker" + current_base_path: "{{ service_base_path }}" + current_destination: "{{ connect_postgres_service_name }}" + current_owner: "{{ docker_owner }}" + current_group: "{{ docker_group }}" + current_docker: "{{ connect_docker }}" + +- name: "Deploy service templates for {{ connect_postgres_service_name }}" + include_role: + name: _deploy + tasks_from: templates + vars: + current_config: "connect" + current_base_path: "{{ service_base_path }}" + current_destination: "{{ connect_postgres_service_name }}" + current_owner: "{{ docker_owner }}" + current_group: "{{ docker_group }}" + +- name: "Update {{ connect_postgres_service_name }}" + shell: docker-compose pull + args: + chdir: '{{ service_base_path }}/{{ connect_postgres_service_name }}' + tags: + - update_deployment + +- name: "Start {{ connect_postgres_service_name }}" + shell: docker-compose up -d + args: + chdir: '{{ service_base_path }}/{{ connect_postgres_service_name }}' + tags: + - update_deployment + +- name: "Send mattermost messsge" + uri: + url: "{{ mattermost_hook_smardigo }}" + method: POST + body: "{{ lookup('template','mattermost-deploy-end.json.j2') }}" + body_format: json + headers: + Content-Type: "application/json" + delegate_to: 127.0.0.1 + become: false + when: + - send_status_messages diff --git a/roles/connect-postgres/vars/main.yml b/roles/connect-postgres/vars/main.yml new file mode 100644 index 0000000..2bfd404 --- /dev/null +++ b/roles/connect-postgres/vars/main.yml @@ -0,0 +1,36 @@ +--- + +connect_postgres_id: "{{ service_name }}-postgres-connect" + +connect_docker: { + networks: [ + { + name: back-tier, + external: true, + } + ], + volumes: [ + { + name: "{{ connect_postgres_id }}-data" + } + ], + services: [ + { + name: "{{ connect_postgres_id }}", + image_name: "postgres", + image_version: "{{ connect_postgres_version }}", + environment: [ + 'POSTGRES_DB: "{{ connect_postgres_database }}"', + 'POSTGRES_USER: "{{ connect_postgres_admin_username }}"', + 'POSTGRES_PASSWORD: "{{ connect_postgres_admin_password }}"', + ], + volumes: [ + '"{{ connect_postgres_id }}-data:/var/lib/postgresql/data"', + ], + networks: [ + '"back-tier"', + ], + ports: "{{ connect_postgres_ports | default([]) }}", + }, + ], +} diff --git a/roles/connect-realm/defaults/main.yml b/roles/connect-realm/defaults/main.yml new file mode 100644 index 0000000..ed97d53 --- /dev/null +++ b/roles/connect-realm/defaults/main.yml @@ -0,0 +1 @@ +--- diff --git a/roles/connect-realm/handlers/main.yml b/roles/connect-realm/handlers/main.yml new file mode 100644 index 0000000..ed97d53 --- /dev/null +++ b/roles/connect-realm/handlers/main.yml @@ -0,0 +1 @@ +--- diff --git a/roles/connect-realm/meta/main.yml b/roles/connect-realm/meta/main.yml new file mode 100644 index 0000000..ed97d53 --- /dev/null +++ b/roles/connect-realm/meta/main.yml @@ -0,0 +1 @@ +--- diff --git a/roles/connect-realm/tasks/main.yml b/roles/connect-realm/tasks/main.yml new file mode 100644 index 0000000..3d85b93 --- /dev/null +++ b/roles/connect-realm/tasks/main.yml @@ -0,0 +1,40 @@ +--- + +### tags: +### update_deployment + +- name: "Send mattermost message" + uri: + url: "{{ mattermost_hook_smardigo }}" + method: POST + body: "{{ lookup('template','mattermost-deploy-start.json.j2') }}" + body_format: json + headers: + Content-Type: "application/json" + delegate_to: 127.0.0.1 + become: false + when: + - send_status_messages + +- name: "Setup realm for {{ service_name }}" + include_role: + name: keycloak + tasks_from: _authenticate + +- name: "Setup realm for {{ service_name }}" + include_role: + name: keycloak + tasks_from: _configure_realm + +- name: "Send mattermost messsge" + uri: + url: "{{ mattermost_hook_smardigo }}" + method: POST + body: "{{ lookup('template','mattermost-deploy-end.json.j2') }}" + body_format: json + headers: + Content-Type: "application/json" + delegate_to: 127.0.0.1 + become: false + when: + - send_status_messages diff --git a/roles/connect-realm/vars/main.yml b/roles/connect-realm/vars/main.yml new file mode 100644 index 0000000..ed97d53 --- /dev/null +++ b/roles/connect-realm/vars/main.yml @@ -0,0 +1 @@ +--- diff --git a/roles/connect/defaults/main.yml b/roles/connect/defaults/main.yml index 252e6c8..f55c581 100644 --- a/roles/connect/defaults/main.yml +++ b/roles/connect/defaults/main.yml @@ -1,15 +1,13 @@ --- +connect_service_name: "{{ service_name }}-connect" + connect_image_name: "{{ docker_registry }}/smardigo/connect-whitelabel-app" connect_version: 'latest' connect_admin_username: "connect-admin" connect_admin_password: "connect-admin" -connect_postgres_version: "12" -connect_postgres_database: "connect-postgres" -connect_postgres_admin_username: "connect-postgres-admin" -connect_postgres_admin_password: "connect-postgres-admin" - connect_mail_properties_base_url: "{{ http_s }}://{{ connect_id }}.{{ domain }}" connect_mail_properties_base_url_extern: "{{ http_s }}://{{ connect_id }}.{{ domain }}" + \ No newline at end of file diff --git a/roles/connect/tasks/main.yml b/roles/connect/tasks/main.yml index d3da5ff..4deea06 100644 --- a/roles/connect/tasks/main.yml +++ b/roles/connect/tasks/main.yml @@ -16,75 +16,75 @@ when: - send_status_messages -- name: "Setup DNS configuration for {{ service_name }}" +- name: "Setup DNS configuration for {{ connect_service_name }}" include_role: name: _digitalocean tasks_from: domain vars: record_data: "{{ stage_server_ip }}" - record_name: "{{ service_name }}" + record_name: "{{ connect_service_name }}" -- name: "Check if {{ service_name }}/docker-compose.yml exists" +- name: "Check if {{ connect_service_name }}/docker-compose.yml exists" stat: - path: '{{ service_base_path }}/{{ service_name }}/docker-compose.yml' + path: '{{ service_base_path }}/{{ connect_service_name }}/docker-compose.yml' register: check_docker_compose_file tags: - update_deployment -- name: "Stop {{ service_name }}" +- name: "Stop {{ connect_service_name }}" shell: docker-compose down args: - chdir: '{{ service_base_path }}/{{ service_name }}' + chdir: '{{ service_base_path }}/{{ connect_service_name }}' when: check_docker_compose_file.stat.exists ignore_errors: yes tags: - update_deployment -- name: "Deploy docker templates for {{ service_name }}" +- name: "Deploy docker templates for {{ connect_service_name }}" include_role: name: _deploy tasks_from: templates vars: current_config: "_docker" current_base_path: "{{ service_base_path }}" - current_destination: "{{ service_name }}" + current_destination: "{{ connect_service_name }}" current_owner: "{{ docker_owner }}" current_group: "{{ docker_group }}" current_docker: "{{ connect_docker }}" -- name: "Deploy service templates for {{ service_name }}" +- name: "Deploy service templates for {{ connect_service_name }}" include_role: name: _deploy tasks_from: templates vars: current_config: "connect" current_base_path: "{{ service_base_path }}" - current_destination: "{{ service_name }}" + current_destination: "{{ connect_service_name }}" current_owner: "{{ docker_owner }}" current_group: "{{ docker_group }}" -- name: "Update {{ service_name }}" +- name: "Update {{ connect_service_name }}" shell: docker-compose pull args: - chdir: '{{ service_base_path }}/{{ service_name }}' + chdir: '{{ service_base_path }}/{{ connect_service_name }}' tags: - update_deployment -- name: "Start {{ service_name }}" +- name: "Start {{ connect_service_name }}" shell: docker-compose up -d args: - chdir: '{{ service_base_path }}/{{ service_name }}' + chdir: '{{ service_base_path }}/{{ connect_service_name }}' tags: - update_deployment -- name: "Update landing page entries for {{ service_name }}" +- name: "Update landing page entries for {{ connect_service_name }}" include_role: name: _deploy tasks_from: caddy_landing_page vars: current_services: [ { - current_name: "{{ service_name }}", + current_name: "{{ connect_service_name }}", current_url: "{{ http_s }}://{{ connect_id }}.{{ domain }}", current_version: "{{ connect_version }}", current_date: "{{ ansible_date_time.iso8601 }}", diff --git a/roles/connect/vars/main.yml b/roles/connect/vars/main.yml index 3684179..7b943a4 100644 --- a/roles/connect/vars/main.yml +++ b/roles/connect/vars/main.yml @@ -88,11 +88,6 @@ connect_docker: { external: true, }, ], - volumes: [ - { - name: "{{ connect_postgres_id }}-data" - } - ], services: [ { name: "{{ connect_id }}", @@ -106,23 +101,6 @@ connect_docker: { '"front-tier"', ], extra_hosts: "{{ connect_extra_hosts | default([]) }}", - }, - { - name: "{{ connect_postgres_id }}", - image_name: "postgres", - image_version: "{{ connect_postgres_version }}", - environment: [ - 'POSTGRES_DB: "{{ connect_postgres_database }}"', - 'POSTGRES_USER: "{{ connect_postgres_admin_username }}"', - 'POSTGRES_PASSWORD: "{{ connect_postgres_admin_password }}"', - ], - volumes: [ - '"{{ connect_postgres_id }}-data:/var/lib/postgresql/data"', - ], - networks: [ - '"back-tier"', - ], - ports: "{{ connect_postgres_ports | default([]) }}", - }, + } ], } diff --git a/roles/keycloak/tasks/_authenticate.yml b/roles/keycloak/tasks/_authenticate.yml new file mode 100644 index 0000000..87b4b68 --- /dev/null +++ b/roles/keycloak/tasks/_authenticate.yml @@ -0,0 +1,22 @@ +--- + +- name: "Authenticate with Keycloak server" + uri: + url: "{{ keycloak_server_url }}/auth/realms/master/protocol/openid-connect/token" + method: POST + body_format: form-urlencoded + body: 'username={{ keycloak_admin_username }}&password={{ keycloak_admin_password }}&client_id=admin-cli&grant_type=password' + register: keycloak_authentication + delegate_to: 127.0.0.1 + retries: 5 + delay: 5 + +- name: Save access_token as variable (fact) + set_fact: + access_token: "{{ keycloak_authentication.json.access_token }}" + delegate_to: 127.0.0.1 + +- name: Print keycloak access_token + debug: + msg: "{{ access_token }}" + delegate_to: 127.0.0.1 \ No newline at end of file diff --git a/roles/keycloak/tasks/_configure_client.yml b/roles/keycloak/tasks/_configure_client.yml new file mode 100644 index 0000000..b4305f3 --- /dev/null +++ b/roles/keycloak/tasks/_configure_client.yml @@ -0,0 +1,19 @@ +--- + +#- name: Print client {{ client_id }} for realm {{ realm_name }} +# debug: +# msg: "{{ lookup('template','keycloak-realm-create-client.json.j2') }}" +# when: realm_client_ids | selectattr('clientId', 'equalto', client_id) | list | length == 0 +# delegate_to: 127.0.0.1 + +- name: Create client {{ client_id }} for realm {{ realm_name }} + uri: + url: "{{ keycloak_server_url }}/auth/admin/realms/{{ realm_name }}/clients" + method: POST + body_format: json + body: "{{ lookup('template','keycloak-realm-create-client.json.j2') }}" + headers: + Authorization: "Bearer {{ access_token}} " + status_code: [201] + when: realm_client_ids | selectattr('clientId', 'equalto', client_id) | list | length == 0 + delegate_to: 127.0.0.1 diff --git a/roles/keycloak/tasks/_configure_realm.yml b/roles/keycloak/tasks/_configure_realm.yml new file mode 100644 index 0000000..edcd2ef --- /dev/null +++ b/roles/keycloak/tasks/_configure_realm.yml @@ -0,0 +1,77 @@ +--- + +- name: Read realms + uri: + url: "{{ keycloak_server_url }}/auth/admin/realms" + method: GET + headers: + Authorization: "Bearer {{ access_token }}" + status_code: [200] + register: realms + delegate_to: 127.0.0.1 + +- name: Save realms as variable (fact) + set_fact: + realms_json: "{{ realms.json }}" + delegate_to: 127.0.0.1 + +- name: Read realm ids + set_fact: + realm_ids: "{{ realms_json | json_query(jmesquery) }}" + vars: + jmesquery: '[*].id' + delegate_to: 127.0.0.1 + +- name: Create realm {{ current_realm_name }} + uri: + url: "{{ keycloak_server_url }}/auth/admin/realms" + method: POST + body_format: json + body: "{{ lookup('template','keycloak-realm-create.json.j2') }}" + headers: + Authorization: "Bearer {{ access_token }}" + status_code: [201] + when: current_realm_name not in realm_ids + delegate_to: 127.0.0.1 + +- name: Read clients from realm {{ current_realm_name }} + uri: + url: "{{ keycloak_server_url }}/auth/admin/realms/{{ current_realm_name }}/clients" + method: GET + headers: + Authorization: "Bearer {{ access_token }}" + status_code: [200] + register: realm_clients + delegate_to: 127.0.0.1 + +- name: Save clients from realm as variable (fact) + set_fact: + realm_clients_json: "{{ realm_clients.json }}" + delegate_to: 127.0.0.1 + +- name: "Save client ids from realm {{ current_realm_name }}" + set_fact: + realm_client_ids: "{{ realm_clients_json | json_query(jmesquery) }}" + vars: + jmesquery: '[*].{id: id, clientId: clientId}' + delegate_to: 127.0.0.1 + +- name: Print client ids + debug: + msg: "{{ realm_client_ids }}" + delegate_to: 127.0.0.1 + +- name: "Create clients from realm {{ current_realm_name }}" + include_tasks: _configure_client.yml + vars: + realm_name: '{{ current_realm_name }}' + client_id: '{{ client.clientId }}' + client_name: '{{ client.name }}' + admin_url: '{{ client.admin_url }}' + root_url: '{{ client.root_url }}' + redirect_uris: '{{ client.redirect_uris }}' + secret: '{{ client.secret }}' + web_origins: '{{ client.web_origins }}' + with_items: "{{ current_realm_clients }}" + loop_control: + loop_var: client diff --git a/roles/keycloak/tasks/configure_client.yml b/roles/keycloak/tasks/configure_client.yml index 6acecf6..6a5a5a2 100644 --- a/roles/keycloak/tasks/configure_client.yml +++ b/roles/keycloak/tasks/configure_client.yml @@ -9,7 +9,7 @@ - name: Create client {{ client_id }} for realm {{ realm_name }} uri: - url: http://localhost:{{ service_port_keycloak_external }}/auth/admin/realms/{{ realm_name }}/clients + url: "{{ keycloak_server_url }}/auth/admin/realms/{{ realm_name }}/clients" method: POST body_format: json body: "{{ lookup('template','keycloak-realm-create-client.json.j2') }}" diff --git a/roles/keycloak/tasks/configure_realm.yml b/roles/keycloak/tasks/configure_realm.yml index 75812de..ee2a97e 100644 --- a/roles/keycloak/tasks/configure_realm.yml +++ b/roles/keycloak/tasks/configure_realm.yml @@ -2,21 +2,15 @@ - name: Read realms uri: - url: http://localhost:{{ service_port_keycloak_external }}/auth/admin/realms + url: "{{ keycloak_server_url }}/auth/admin/realms" method: GET headers: - Authorization: "Bearer {{ access_token}} " + Authorization: "Bearer {{ access_token }}" status_code: [200] register: realms tags: - update_realms -#- name: Print realms -# debug: -# msg: "{{ realms }}" -# tags: -# - update_realms - - name: Save realms as variable (fact) set_fact: realms_json: "{{ realms.json }}" @@ -25,7 +19,7 @@ - name: Read realm ids set_fact: - realm_ids: "{{ realms_json | json_query(jmesquery) }}" + realm_ids: "{{ realms_json | json_query(jmesquery) }}" vars: jmesquery: '[*].id' tags: @@ -33,12 +27,12 @@ - name: Create realm {{ current_realm_name }} uri: - url: http://localhost:{{ service_port_keycloak_external }}/auth/admin/realms + url: "{{ keycloak_server_url }}/auth/admin/realms" method: POST body_format: json body: "{{ lookup('template','keycloak-realm-create.json.j2') }}" headers: - Authorization: "Bearer {{ access_token}} " + Authorization: "Bearer {{ access_token }}" status_code: [201] when: current_realm_name not in realm_ids tags: @@ -46,21 +40,15 @@ - name: Read clients from realm {{ current_realm_name }} uri: - url: http://localhost:{{ service_port_keycloak_external }}/auth/admin/realms/{{ current_realm_name }}/clients + url: "{{ keycloak_server_url }}/auth/admin/realms/{{ current_realm_name }}/clients" method: GET headers: - Authorization: "Bearer {{ access_token}} " + Authorization: "Bearer {{ access_token }}" status_code: [200] register: realm_clients tags: - update_realms -#- name: Print clients from realm {{ current_realm_name }} -# debug: -# msg: "{{ realm_clients }}" -# tags: -# - update_realms - - name: Save clients from realm as variable (fact) set_fact: realm_clients_json: "{{ realm_clients.json }}" @@ -69,7 +57,7 @@ - name: Save client ids from realm {{ current_realm_name }} set_fact: - realm_client_ids: "{{ realm_clients_json | json_query(jmesquery) }}" + realm_client_ids: "{{ realm_clients_json | json_query(jmesquery) }}" vars: jmesquery: '[*].{id: id, clientId: clientId}' tags: @@ -98,22 +86,3 @@ loop_var: client tags: - update_realms - -- name: Create realm {{ current_realm_name }} LDAP user storage provider - include_tasks: configure_user_storage_provider_ldap.yml - vars: - realm: '{{ current_realm_name }}' - provider_name: '{{ provider.name }}' - usersDn: '{{ provider.usersDn }}' - ldap_username: '{{ provider.username }}' - ldap_password: '{{ provider.password }}' - ldap_connection_url: '{{ provider.connection_url }}' - ldap_username_attribute: '{{ provider.username_attribute }}' - custom_user_search_filter: '{{ provider.custom_user_search_filter }}' - search_scope: '{{ provider.search_scope }}' - access_token: '{{ keycloak_authentication.json.access_token }}' - with_items: "{{ current_realm_ldaps }}" - loop_control: - loop_var: provider - tags: - - update_realms diff --git a/roles/keycloak/tasks/configure_user_storage_provider_ldap.yml b/roles/keycloak/tasks/configure_user_storage_provider_ldap.yml deleted file mode 100644 index 3492d27..0000000 --- a/roles/keycloak/tasks/configure_user_storage_provider_ldap.yml +++ /dev/null @@ -1,107 +0,0 @@ -- name: Create ldap user storage provider in realm {{ realm }} - uri: - url: http://localhost:{{ service_port_keycloak_external }}/auth/admin/realms/{{ realm }}/components - method: POST - body_format: json - body: '{ - "name": "{{ provider_name }}", - "providerId": "ldap", - "providerType": "org.keycloak.storage.UserStorageProvider", - "parentId": "{{ realm }}", - "config": { - "allowKerberosAuthentication": ["false"], - "authType": ["simple"], - "batchSizeForSync": ["1000"], - "bindCredential": ["{{ ldap_password }}"], - "bindDn": ["{{ ldap_username }}"], - "cachePolicy": ["DEFAULT"], - "changedSyncPeriod": ["86400"], - "connectionPooling": ["true"], - "connectionUrl": ["{{ ldap_connection_url }}"], - "customUserSearchFilter": ["{{ custom_user_search_filter }}"], - "debug": ["false"], - "editMode": ["READ_ONLY"], - "enabled": ["true"], - "fullSyncPeriod": ["604800"], - "importEnabled": ["true"], - "pagination": ["true"], - "priority": ["0"], - "rdnLDAPAttribute": ["cn"], - "searchScope": ["{{ search_scope }}"], - "syncRegistrations": ["false"], - "trustEmail": ["false"], - "useKerberosForPasswordAuthentication": ["false"], - "usernameLDAPAttribute": ["{{ ldap_username_attribute }}"], - "userObjectClasses": ["person, organizationalPerson, user"], - "usersDn": ["{{ usersDn }}"], - "useTruststoreSpi": ["ldapsOnly"], - "uuidLDAPAttribute": ["objectGUID"], - "validatePasswordPolicy": ["false"], - "vendor": ["ad"] - } - }' - status_code: [201] - headers: - Authorization: "Bearer {{ access_token }}" - register: response - tags: - - update_realms - -- name: Get id of created user storage provider - uri: - url: "{{ response.location }}" - method: GET - headers: - Authorization: "Bearer {{ access_token }}" - register: response - tags: - - update_realms - -- name: Create user attribute mapper for firstName - uri: - url: http://localhost:{{ service_port_keycloak_external }}/auth/admin/realms/{{ realm }}/components - method: POST - body_format: json - body: '{ - "name": "first name", - "providerId": "user-attribute-ldap-mapper", - "providerType": "org.keycloak.storage.ldap.mappers.LDAPStorageMapper", - "parentId": "{{ response.json.id }}", - "config": { - "ldap.attribute": ["givenName"], - "is.mandatory.in.ldap": ["false"], - "is.binary.attribute": ["false"], - "read.only": ["true"], - "always.read.value.from.ldap": ["false"], - "user.model.attribute": ["firstName"] - } - }' - headers: - Authorization: "Bearer {{ access_token }}" - status_code: [201] - tags: - - update_realms - -- name: Create user role mappers - uri: - url: http://localhost:{{ service_port_keycloak_external }}/auth/admin/realms/{{ realm }}/components - method: POST - body_format: json - body: '{ - "name": "{{ role.name }}", - "providerId": "hardcoded-ldap-role-mapper", - "providerType": "org.keycloak.storage.ldap.mappers.LDAPStorageMapper", - "config": { - "role": ["{{ role.role_id }}"], - }, - "parentId": "{{ response.json.id }}", - }' - headers: - Authorization: "Bearer {{ access_token }}" - status_code: [201] - when: hardcoded_user_roles is defined - with_items: "{{ hardcoded_user_roles }}" - loop_control: - loop_var: role - tags: - - update_realms \ No newline at end of file diff --git a/roles/keycloak/tasks/main.yml b/roles/keycloak/tasks/main.yml index ae28fed..329682f 100644 --- a/roles/keycloak/tasks/main.yml +++ b/roles/keycloak/tasks/main.yml @@ -115,32 +115,12 @@ - create_groups - update_realms -- name: "Create user storage provider in master realm" - include_tasks: configure_user_storage_provider_ldap.yml - vars: - access_token: "{{ keycloak_authentication.json.access_token }}" - realm: master - provider_name: '{{ item.name }}' - ldap_username: '{{ item.username }}' - ldap_password: '{{ item.password }}' - ldap_connection_url: '{{ item.connection_url }}' - ldap_username_attribute: '{{ item.username_attribute }}' - usersDn: '{{ item.usersDn }}' - custom_user_search_filter: '{{ item.custom_user_search_filter }}' - search_scope: '{{ item.search_scope }}' - hardcoded_user_roles: '{{ item.hardcoded_user_roles }}' - with_items: "{{ keycloak.master.ldap | default([]) }}" - when: keycloak.master is defined - tags: - - update_realms - - name: "Setup realms" include_tasks: configure_realm.yml vars: current_realm_name: '{{ current_realm.name }}' current_realm_display_name: '{{ current_realm.display_name }}' current_realm_clients: '{{ current_realm.clients | default([]) }}' - current_realm_ldaps: '{{ current_realm.ldaps | default([]) }}' access_token: "{{ keycloak_authentication.json.access_token }}" with_items: "{{ keycloak.realms }}" loop_control: diff --git a/smardigo/provisioning/app/process.json b/smardigo/provisioning/app/process.json new file mode 100644 index 0000000..0b6b877 --- /dev/null +++ b/smardigo/provisioning/app/process.json @@ -0,0 +1,77 @@ +{ + "name" : "Smardigo Provisioning", + "configKey" : "process", + "configType" : "process", + "description" : "Provisioning and configuration for smardigo instances", + "imageUrl" : "data:image/png;base64,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", + "menuItems" : [ { + "name" : "Provisioning", + "tabName" : "Provisioning", + "logoId" : "cube", + "configType" : "process-search", + "processDefinitionKey" : "simple-connect", + "processDefinitionKeys" : [ "simple-connect" ], + "groups" : [ "user", "head", "maintainer", "administrator" ] + }, { + "name" : "navbar.workflow", + "logoId" : "cogs", + "configType" : "menu", + "groups" : [ "administrator" ], + "items" : [ { + "name" : "navbar.workflow.scope_tags", + "logoId" : "cogs", + "configType" : "process-config", + "configKey" : "scope-tags" + }, { + "name" : "navbar.workflow.processes", + "logoId" : "cogs", + "configType" : "process-config", + "configKey" : "processes" + }, { + "name" : "navbar.workflow.process_searches", + "logoId" : "search", + "configType" : "process-config", + "configKey" : "process-searches" + }, { + "name" : "navbar.workflow.process_variable_declarations", + "logoId" : "file-code-o", + "configType" : "process-config", + "configKey" : "process-variable-declarations" + }, { + "name" : "navbar.workflow.layouts", + "logoId" : "newspaper-o", + "configType" : "process-config", + "configKey" : "layouts" + }, { + "name" : "navbar.workflow.forms", + "logoId" : "list-alt", + "configType" : "process-config", + "configKey" : "forms" + }, { + "name" : "navbar.workflow.datasources", + "logoId" : "fw fa-database", + "configType" : "process-config", + "configKey" : "datasources" + }, { + "name" : "navbar.workflow.mail_templates", + "logoId" : "envelope", + "configType" : "process-config", + "configKey" : "mail-templates" + }, { + "name" : "navbar.workflow.process_presets", + "logoId" : "book", + "configType" : "process-config", + "configKey" : "process-presets" + }, { + "name" : "navbar.workflow.document_templates", + "logoId" : "cubes", + "configType" : "process-config", + "configKey" : "document-templates" + }, { + "name" : "config.type.name2", + "logoId" : "edit", + "configType" : "process-config", + "configKey" : "configs" + } ] + } ] +} \ No newline at end of file diff --git a/smardigo/provisioning/datasource-file/master_data.xlsx b/smardigo/provisioning/datasource-file/master_data.xlsx new file mode 100644 index 0000000..8bde9f3 Binary files /dev/null and b/smardigo/provisioning/datasource-file/master_data.xlsx differ diff --git a/smardigo/provisioning/datasource/accounts.json b/smardigo/provisioning/datasource/accounts.json new file mode 100644 index 0000000..5fdd039 --- /dev/null +++ b/smardigo/provisioning/datasource/accounts.json @@ -0,0 +1,31 @@ +{ + "name" : "Accounts", + "restApi" : true, + "configKey" : "accounts", + "payloadType" : "EXCEL", + "config" : [ { + "name" : "file", + "type" : "FILE", + "value" : "master_data.xlsx" + }, { + "name" : "columnNames", + "type" : "STRING", + "value" : "" + }, { + "name" : "sqlStatement", + "type" : "STRING", + "value" : "select * from accounts" + }, { + "name" : "columnNameLineNumber", + "type" : "INT", + "value" : 1 + }, { + "name" : "skipEmptyLines", + "type" : "BOOLEAN", + "value" : false + }, { + "name" : "skipEmptyColumns", + "type" : "BOOLEAN", + "value" : false + } ] +} \ No newline at end of file diff --git a/smardigo/provisioning/datasource/tenants.json b/smardigo/provisioning/datasource/tenants.json new file mode 100644 index 0000000..00274a4 --- /dev/null +++ b/smardigo/provisioning/datasource/tenants.json @@ -0,0 +1,17 @@ +{ + "name" : "Mandanten", + "restApi" : true, + "configKey" : "tenants", + "payloadType" : "ENTITY", + "config" : [ { + "name" : "entityId", + "type" : "STRING", + "value" : "tenants" + }, { + "name" : "propertyFilterKey", + "type" : "STRING" + }, { + "name" : "propertyFilterValue", + "type" : "STRING" + } ] +} \ No newline at end of file diff --git a/smardigo/provisioning/form/approve.json b/smardigo/provisioning/form/approve.json new file mode 100644 index 0000000..2632169 --- /dev/null +++ b/smardigo/provisioning/form/approve.json @@ -0,0 +1,178 @@ +{ + "name" : "Dialog zur Freigabe", + "configKey" : "approve", + "display" : "form", + "page" : 0, + "components" : [ { + "label" : "Entscheidung", + "mask" : false, + "tableView" : true, + "alwaysEnabled" : false, + "type" : "select", + "input" : true, + "key" : "antrag_decission", + "defaultValue" : "", + "validate" : { + "customMessage" : "", + "json" : "", + "required" : true, + "select" : false, + "custom" : "", + "customPrivate" : false + }, + "conditional" : { + "show" : "", + "when" : "", + "json" : "", + "eq" : "" + }, + "data" : { + "custom" : "values = [\n { \"label\": \"Antrag ablehnen\", \"value\": \"antragAblehnen\" }\n];\nif (true) {\n values.splice(1, 0, { \"label\": \"Antrag genehmigen\", \"value\": \"antragGenehmigen\" });\n}", + "values" : [ ], + "json" : "", + "url" : "", + "resource" : "" + }, + "valueProperty" : "value", + "selectThreshold" : 0.3, + "encrypted" : false, + "properties" : { }, + "customConditional" : "", + "logic" : [ ], + "tags" : [ ], + "dataSrc" : "custom", + "searchEnabled" : false, + "tabs" : null, + "reorder" : false, + "lazyLoad" : false, + "selectValues" : "", + "disableLimit" : false, + "sort" : "", + "reference" : false, + "placeholder" : "", + "prefix" : "", + "customClass" : "", + "suffix" : "", + "multiple" : false, + "protected" : false, + "unique" : false, + "persistent" : true, + "hidden" : false, + "clearOnHide" : true, + "dataGridLabel" : false, + "labelPosition" : "top", + "labelWidth" : 30, + "labelMargin" : 3, + "description" : "", + "errorLabel" : "", + "tooltip" : "", + "hideLabel" : false, + "tabindex" : "", + "disabled" : false, + "autofocus" : false, + "dbIndex" : false, + "customDefaultValue" : "", + "calculateValue" : "", + "allowCalculateOverride" : false, + "widget" : null, + "refreshOn" : "", + "clearOnRefresh" : false, + "validateOn" : "change", + "limit" : 100, + "filter" : "", + "searchField" : "", + "minSearch" : 0, + "readOnlyValue" : false, + "authenticate" : false, + "template" : "{{ item.label }}", + "selectFields" : "", + "customSearchCriteria" : "", + "searchThreshold" : 0.3, + "fuseOptions" : { }, + "customOptions" : { }, + "infiniteScroll" : false, + "clearValueIfNotInItems" : false, + "clientSideFilter" : "", + "id" : "e9osarl" + }, { + "label" : "Bitte hinterlegen Sie einen Kommentar", + "isUploadEnabled" : false, + "showWordCount" : false, + "showCharCount" : false, + "autofocus" : true, + "tableView" : true, + "alwaysEnabled" : false, + "wysiwyg" : "", + "rows" : 5, + "type" : "textarea", + "input" : true, + "key" : "approve_comment:createComment", + "defaultValue" : "", + "validate" : { + "unique" : false, + "json" : "", + "required" : false, + "custom" : "", + "customPrivate" : false, + "minLength" : "", + "maxLength" : "", + "minWords" : "", + "maxWords" : "", + "pattern" : "" + }, + "properties" : { }, + "tags" : [ ], + "inputFormat" : "plain", + "spellcheck" : true, + "conditional" : { + "show" : "", + "when" : "", + "json" : "", + "eq" : "" + }, + "encrypted" : false, + "logic" : [ ], + "customConditional" : "", + "uploadUrl" : "", + "uploadOptions" : "", + "uploadDir" : "", + "reorder" : false, + "placeholder" : "", + "prefix" : "", + "customClass" : "", + "suffix" : "", + "multiple" : false, + "protected" : false, + "unique" : false, + "persistent" : true, + "hidden" : false, + "clearOnHide" : true, + "dataGridLabel" : false, + "labelPosition" : "top", + "labelWidth" : 30, + "labelMargin" : 3, + "description" : "", + "errorLabel" : "", + "tooltip" : "", + "hideLabel" : false, + "tabindex" : "", + "disabled" : false, + "dbIndex" : false, + "customDefaultValue" : "", + "calculateValue" : "", + "allowCalculateOverride" : false, + "widget" : { + "format" : "yyyy-MM-dd hh:mm a", + "dateFormat" : "yyyy-MM-dd hh:mm a", + "saveAs" : "text" + }, + "refreshOn" : "", + "clearOnRefresh" : false, + "validateOn" : "change", + "mask" : false, + "inputType" : "text", + "inputMask" : "", + "editor" : "", + "id" : "e3y1fri" + } ] +} \ No newline at end of file diff --git a/smardigo/provisioning/form/attachments.json b/smardigo/provisioning/form/attachments.json new file mode 100644 index 0000000..4d981bf --- /dev/null +++ b/smardigo/provisioning/form/attachments.json @@ -0,0 +1,87 @@ +{ + "name" : "Anhänge", + "configKey" : "attachments", + "page" : 0, + "components" : [ { + "dropzoneConfig" : { + "maxFilesize" : "10", + "dictDefaultMessage" : "Dateien zum Anhängen/Hochladen ablegen oder durchsuchen", + "dictHelpText" : "Maximale Dateigröße: {{config.maxFilesize}}MB. Akzeptierte Dateitypen: Office-Dokumente und Bilder.", + "acceptedFiles" : ".pdf, .doc, .docx, .xls, .xlsx, .ppt, .pptx, image/*, .csv, .xml, .txt", + "paramName" : "content", + "url" : "api/scope/{{context.scopeId}}/process/{{context.processId}}/attachment" + }, + "columns" : [ { + "name" : "Name", + "property" : "name", + "value" : "", + "type" : "filename", + "width" : "20%" + }, { + "name" : "Erstellt am", + "property" : "creationDate", + "type" : "date", + "value" : "{{moment(creationDate).format('DD.MM.YYYY HH:mm:ss')}}", + "width" : "80%" + } ], + "label" : "Anlagen", + "deleteUrl" : "api/scope/{{context.scopeId}}/process/{{context.processId}}/attachment/{{attachmentId}}", + "downloadUrl" : "api/scope/{{context.scopeId}}/process/{{context.processId}}/attachment-data/{{attachmentId}}", + "resolveUserDataURL" : "api/scope/{{context.scopeId}}/process/{{context.processId}}/users?id.equals={{userId}}", + "csrfCookiePath" : "XSRF-TOKEN", + "taggingExpression" : "", + "button" : { + "iconOnly" : true, + "removeVisibleWhen" : "return false;", + "showVersion" : false, + "showOnlyCurrentVersion" : false, + "showCheckboxCurrentVersion" : false + }, + "mask" : false, + "tableView" : true, + "type" : "attachments", + "input" : true, + "key" : "anlagen", + "components" : [ ], + "placeholder" : "", + "prefix" : "", + "customClass" : "", + "suffix" : "", + "multiple" : false, + "defaultValue" : null, + "protected" : false, + "unique" : false, + "persistent" : true, + "hidden" : false, + "clearOnHide" : true, + "dataGridLabel" : false, + "labelPosition" : "top", + "labelWidth" : 30, + "labelMargin" : 3, + "description" : "", + "errorLabel" : "", + "tooltip" : "", + "hideLabel" : true, + "tabindex" : "", + "disabled" : false, + "autofocus" : false, + "dbIndex" : false, + "customDefaultValue" : "", + "calculateValue" : "", + "widget" : null, + "refreshOn" : "", + "clearOnRefresh" : false, + "validateOn" : "change", + "validate" : { + "required" : false, + "custom" : "", + "customPrivate" : false + }, + "conditional" : { + "show" : null, + "when" : null, + "eq" : "" + }, + "id" : "e9zp29e" + } ] +} \ No newline at end of file diff --git a/smardigo/provisioning/form/header.json b/smardigo/provisioning/form/header.json new file mode 100644 index 0000000..e7e7678 --- /dev/null +++ b/smardigo/provisioning/form/header.json @@ -0,0 +1,435 @@ +{ + "name" : "Kopfzeile", + "configKey" : "header", + "page" : 0, + "components" : [ { + "input" : false, + "tableView" : false, + "columns" : [ { + "components" : [ { + "labelPosition" : "left-right", + "label" : "Ersteller", + "mask" : false, + "disabled" : true, + "tableView" : true, + "type" : "select", + "input" : true, + "key" : "creation_user_id", + "validate" : { + "unique" : false, + "customMessage" : "", + "json" : "", + "required" : false, + "custom" : "", + "customPrivate" : false + }, + "data" : { + "headers" : [ { + "key" : "", + "value" : "" + } ], + "url" : "api/v1/scopes/{{context.scopeId}}/processes/{{context.processId}}/users?id.equals={{data.creation_user_id}}", + "values" : [ ], + "json" : "", + "resource" : "", + "custom" : "" + }, + "properties" : { }, + "tags" : [ ], + "defaultValue" : "", + "dataSrc" : "url", + "lazyLoad" : false, + "valueProperty" : "id", + "selectValues" : "", + "disableLimit" : false, + "template" : "{{[item.firstName, item.lastName].filter(Boolean).join(' ')}}", + "placeholder" : "", + "prefix" : "", + "customClass" : "", + "suffix" : "", + "multiple" : false, + "protected" : false, + "unique" : false, + "persistent" : true, + "hidden" : false, + "clearOnHide" : true, + "dataGridLabel" : false, + "labelWidth" : 30, + "labelMargin" : 3, + "description" : "", + "errorLabel" : "", + "tooltip" : "", + "hideLabel" : false, + "tabindex" : "", + "autofocus" : false, + "dbIndex" : false, + "customDefaultValue" : "", + "calculateValue" : "", + "widget" : null, + "refreshOn" : "", + "clearOnRefresh" : false, + "validateOn" : "change", + "conditional" : { + "show" : null, + "when" : null, + "eq" : "" + }, + "filter" : "", + "searchEnabled" : false, + "searchField" : "", + "minSearch" : 0, + "authenticate" : false, + "selectFields" : "", + "id" : "eiwhw5a" + } ], + "width" : 4, + "offset" : 0, + "push" : 0, + "pull" : 0, + "type" : "column", + "input" : true, + "key" : "", + "tableView" : true, + "label" : "", + "placeholder" : "", + "prefix" : "", + "customClass" : "", + "suffix" : "", + "multiple" : false, + "defaultValue" : null, + "protected" : false, + "unique" : false, + "persistent" : true, + "hidden" : false, + "clearOnHide" : true, + "dataGridLabel" : false, + "labelPosition" : "top", + "labelWidth" : 30, + "labelMargin" : 3, + "description" : "", + "errorLabel" : "", + "tooltip" : "", + "hideLabel" : false, + "tabindex" : "", + "disabled" : false, + "autofocus" : false, + "dbIndex" : false, + "customDefaultValue" : "", + "calculateValue" : "", + "widget" : null, + "refreshOn" : "", + "clearOnRefresh" : false, + "validateOn" : "change", + "validate" : { + "required" : false, + "custom" : "", + "customPrivate" : false + }, + "conditional" : { + "show" : null, + "when" : null, + "eq" : "" + }, + "id" : "eshoyow" + }, { + "components" : [ { + "labelPosition" : "left-right", + "label" : "Erstellt am", + "format" : "dd.MM.yyyy", + "mask" : false, + "tableView" : true, + "type" : "datetime", + "input" : true, + "key" : "creation_date", + "suffix" : true, + "widget" : { + "type" : "calendar", + "displayInTimezone" : "viewer", + "language" : "en", + "useLocaleSettings" : false, + "allowInput" : true, + "mode" : "single", + "enableTime" : true, + "noCalendar" : false, + "format" : "dd-MM-yyyy", + "defaultDate" : "", + "hourIncrement" : 1, + "minuteIncrement" : 1, + "time_24hr" : false, + "minDate" : null, + "maxDate" : null + }, + "defaultValue" : "", + "defaultDate" : "", + "placeholder" : "", + "prefix" : "", + "customClass" : "", + "multiple" : false, + "protected" : false, + "unique" : false, + "persistent" : true, + "hidden" : false, + "clearOnHide" : true, + "dataGridLabel" : false, + "labelWidth" : 30, + "labelMargin" : 3, + "description" : "", + "errorLabel" : "", + "tooltip" : "", + "hideLabel" : false, + "tabindex" : "", + "disabled" : false, + "autofocus" : false, + "dbIndex" : false, + "customDefaultValue" : "", + "calculateValue" : "", + "refreshOn" : "", + "clearOnRefresh" : false, + "validateOn" : "change", + "validate" : { + "required" : false, + "custom" : "", + "customPrivate" : false + }, + "conditional" : { + "show" : null, + "when" : null, + "eq" : "" + }, + "useLocaleSettings" : false, + "allowInput" : true, + "enableDate" : true, + "enableTime" : true, + "displayInTimezone" : "viewer", + "timezone" : "", + "datepickerMode" : "day", + "datePicker" : { + "showWeeks" : true, + "startingDay" : 0, + "initDate" : "", + "minMode" : "day", + "maxMode" : "year", + "yearRows" : 4, + "yearColumns" : 5, + "minDate" : null, + "maxDate" : null + }, + "timePicker" : { + "hourStep" : 1, + "minuteStep" : 1, + "showMeridian" : true, + "readonlyInput" : false, + "mousewheel" : true, + "arrowkeys" : true + }, + "id" : "epdpyie" + } ], + "width" : 4, + "offset" : 0, + "push" : 0, + "pull" : 0, + "type" : "column", + "input" : true, + "key" : "", + "tableView" : true, + "label" : "", + "placeholder" : "", + "prefix" : "", + "customClass" : "", + "suffix" : "", + "multiple" : false, + "defaultValue" : null, + "protected" : false, + "unique" : false, + "persistent" : true, + "hidden" : false, + "clearOnHide" : true, + "dataGridLabel" : false, + "labelPosition" : "top", + "labelWidth" : 30, + "labelMargin" : 3, + "description" : "", + "errorLabel" : "", + "tooltip" : "", + "hideLabel" : false, + "tabindex" : "", + "disabled" : false, + "autofocus" : false, + "dbIndex" : false, + "customDefaultValue" : "", + "calculateValue" : "", + "widget" : null, + "refreshOn" : "", + "clearOnRefresh" : false, + "validateOn" : "change", + "validate" : { + "required" : false, + "custom" : "", + "customPrivate" : false + }, + "conditional" : { + "show" : null, + "when" : null, + "eq" : "" + }, + "id" : "ezh6tkh" + }, { + "components" : [ { + "input" : true, + "tableView" : false, + "label" : "Status", + "key" : "vorgang_status_text", + "defaultValue" : "", + "persistent" : false, + "clearOnHide" : false, + "conditional" : { + "show" : "", + "when" : null, + "eq" : "" + }, + "type" : "textfield", + "labelPosition" : "left-right", + "tags" : [ ], + "properties" : { + "" : "" + }, + "labelWidth" : 40, + "disabled" : true, + "lockKey" : true, + "placeholder" : "", + "prefix" : "", + "customClass" : "", + "suffix" : "", + "multiple" : false, + "protected" : false, + "unique" : false, + "hidden" : false, + "dataGridLabel" : false, + "labelMargin" : 3, + "description" : "", + "errorLabel" : "", + "tooltip" : "", + "hideLabel" : false, + "tabindex" : "", + "autofocus" : false, + "dbIndex" : false, + "customDefaultValue" : "", + "calculateValue" : "", + "widget" : null, + "refreshOn" : "", + "clearOnRefresh" : false, + "validateOn" : "change", + "validate" : { + "required" : false, + "custom" : "", + "customPrivate" : false, + "minLength" : "", + "maxLength" : "", + "minWords" : "", + "maxWords" : "", + "pattern" : "" + }, + "mask" : false, + "inputType" : "text", + "inputMask" : "", + "id" : "eay7qmt" + } ], + "width" : 4, + "offset" : 0, + "push" : 0, + "pull" : 0, + "type" : "column", + "input" : true, + "key" : "", + "tableView" : true, + "label" : "", + "placeholder" : "", + "prefix" : "", + "customClass" : "", + "suffix" : "", + "multiple" : false, + "defaultValue" : null, + "protected" : false, + "unique" : false, + "persistent" : true, + "hidden" : false, + "clearOnHide" : true, + "dataGridLabel" : false, + "labelPosition" : "top", + "labelWidth" : 30, + "labelMargin" : 3, + "description" : "", + "errorLabel" : "", + "tooltip" : "", + "hideLabel" : false, + "tabindex" : "", + "disabled" : false, + "autofocus" : false, + "dbIndex" : false, + "customDefaultValue" : "", + "calculateValue" : "", + "widget" : null, + "refreshOn" : "", + "clearOnRefresh" : false, + "validateOn" : "change", + "validate" : { + "required" : false, + "custom" : "", + "customPrivate" : false + }, + "conditional" : { + "show" : null, + "when" : null, + "eq" : "" + }, + "id" : "ex6xngr" + } ], + "type" : "columns", + "tags" : [ ], + "conditional" : { + "show" : "", + "when" : null, + "eq" : "" + }, + "properties" : { + "" : "" + }, + "label" : "Columns", + "placeholder" : "", + "prefix" : "", + "customClass" : "", + "suffix" : "", + "multiple" : false, + "defaultValue" : null, + "protected" : false, + "unique" : false, + "persistent" : false, + "hidden" : false, + "clearOnHide" : false, + "dataGridLabel" : false, + "labelPosition" : "top", + "labelWidth" : 30, + "labelMargin" : 3, + "description" : "", + "errorLabel" : "", + "tooltip" : "", + "hideLabel" : false, + "tabindex" : "", + "disabled" : false, + "autofocus" : false, + "dbIndex" : false, + "customDefaultValue" : "", + "calculateValue" : "", + "widget" : null, + "refreshOn" : "", + "clearOnRefresh" : false, + "validateOn" : "change", + "validate" : { + "required" : false, + "custom" : "", + "customPrivate" : false + }, + "autoAdjust" : false, + "id" : "eoi1e6" + } ] +} \ No newline at end of file diff --git a/smardigo/provisioning/form/simple-connect-create.json b/smardigo/provisioning/form/simple-connect-create.json new file mode 100644 index 0000000..8d032db --- /dev/null +++ b/smardigo/provisioning/form/simple-connect-create.json @@ -0,0 +1,1240 @@ +{ + "name" : "Simple Connect Wizard", + "configKey" : "simple-connect-create", + "display" : "wizard", + "page" : 0, + "numPages" : 8, + "components" : [ { + "labelPosition" : "left", + "label" : "Auswahl Mandant", + "title" : "Auswahl Mandant", + "tableView" : false, + "type" : "panel", + "components" : [ { + "label" : "Mandant auswählen", + "hideLabel" : true, + "optionsLabelPosition" : "right", + "values" : [ { + "label" : "Mandant anlegen", + "value" : "create_new_tenant", + "shortcut" : "" + }, { + "shortcut" : "", + "label" : "Mandant auswählen", + "value" : "choose_tenant" + } ], + "inline" : false, + "persistent" : false, + "clearOnHide" : false, + "mask" : false, + "tableView" : true, + "alwaysEnabled" : false, + "type" : "radio", + "input" : true, + "key" : "wizard_selection", + "validate" : { + "unique" : false, + "customMessage" : "", + "json" : "", + "required" : true, + "custom" : "", + "customPrivate" : false + }, + "properties" : { }, + "tags" : [ ], + "conditional" : { + "show" : "", + "when" : "", + "json" : "", + "eq" : "" + }, + "customConditional" : "", + "logic" : [ ], + "defaultValue" : "choose_tenant", + "encrypted" : false, + "tabs" : null, + "reorder" : false, + "placeholder" : "", + "prefix" : "", + "customClass" : "", + "suffix" : "", + "multiple" : false, + "protected" : false, + "unique" : false, + "hidden" : false, + "dataGridLabel" : false, + "labelPosition" : "top", + "labelWidth" : 30, + "labelMargin" : 3, + "description" : "", + "errorLabel" : "", + "tooltip" : "", + "tabindex" : "", + "disabled" : false, + "autofocus" : false, + "dbIndex" : false, + "customDefaultValue" : "", + "calculateValue" : "", + "allowCalculateOverride" : false, + "widget" : null, + "refreshOn" : "", + "clearOnRefresh" : false, + "validateOn" : "change", + "inputType" : "radio", + "fieldSet" : false, + "id" : "evn9swg" + }, { + "label" : "Mandant", + "hideLabel" : true, + "mask" : false, + "tableView" : true, + "type" : "container", + "input" : true, + "key" : "tenant", + "components" : [ { + "label" : "Mandant", + "customClass" : "ml-4", + "clearOnHide" : false, + "mask" : false, + "tableView" : true, + "alwaysEnabled" : false, + "type" : "listselection", + "input" : true, + "key" : "selected_tenant", + "data" : { + "url" : "/api/v1/scopes/{{context.scopeId}}/tags/{{context.scopeTag}}/datasources/tenants/query", + "requestBody" : "", + "values" : [ { } ], + "method" : "GET" + }, + "columns" : [ { + "name" : "Name", + "prop" : "name", + "value" : "", + "width" : "", + "sortable" : true + }, { + "name" : "Schlüssel", + "prop" : "key", + "value" : "", + "width" : "", + "sortable" : true + } ], + "projection" : [ { + "key" : "id", + "prop" : "id" + }, { + "key" : "name", + "prop" : "name" + }, { + "key" : "key", + "prop" : "key" + } ], + "identity" : "id", + "validate" : { + "required" : true, + "unique" : false, + "customMessage" : "", + "json" : "", + "custom" : "", + "customPrivate" : false + }, + "properties" : { }, + "tags" : [ ], + "conditional" : { + "show" : "", + "when" : "", + "json" : "", + "eq" : "" + }, + "customConditional" : "show = data.wizard_selection == 'choose_tenant';", + "logic" : [ { + "name" : "if wizard_selection = 'create_new_tenant' then clear", + "trigger" : { + "type" : "javascript", + "javascript" : "result = data.wizard_selection == 'create_new_tenant';" + }, + "actions" : [ { + "name" : "clear", + "type" : "clear" + } ] + } ], + "tabs" : null, + "datapath" : "", + "defaultFilter" : "", + "encrypted" : false, + "reorder" : false, + "placeholder" : "", + "prefix" : "", + "suffix" : "", + "multiple" : false, + "defaultValue" : null, + "protected" : false, + "unique" : false, + "persistent" : true, + "hidden" : false, + "dataGridLabel" : false, + "labelPosition" : "top", + "labelWidth" : 30, + "labelMargin" : 3, + "description" : "", + "errorLabel" : "", + "tooltip" : "", + "hideLabel" : false, + "tabindex" : "", + "disabled" : false, + "autofocus" : false, + "dbIndex" : false, + "customDefaultValue" : "", + "calculateValue" : "", + "allowCalculateOverride" : false, + "widget" : null, + "refreshOn" : "", + "clearOnRefresh" : false, + "validateOn" : "change", + "dataSrc" : "url", + "filter" : true, + "filterPlaceholder" : "Tippen um zu filtern.", + "rowTooltip" : "", + "rowClassifier" : "", + "characterThreshold" : 0, + "id" : "evax5dd" + } ], + "properties" : { }, + "clearOnHide" : false, + "placeholder" : "", + "prefix" : "", + "customClass" : "", + "suffix" : "", + "multiple" : false, + "defaultValue" : null, + "protected" : false, + "unique" : false, + "persistent" : true, + "hidden" : false, + "dataGridLabel" : false, + "labelPosition" : "top", + "labelWidth" : 30, + "labelMargin" : 3, + "description" : "", + "errorLabel" : "", + "tooltip" : "", + "tabindex" : "", + "disabled" : false, + "autofocus" : false, + "dbIndex" : false, + "customDefaultValue" : "", + "calculateValue" : "", + "allowCalculateOverride" : false, + "widget" : null, + "refreshOn" : "", + "clearOnRefresh" : false, + "validateOn" : "change", + "validate" : { + "required" : false, + "custom" : "", + "customPrivate" : false + }, + "conditional" : { + "show" : null, + "when" : null, + "eq" : "" + }, + "tree" : true, + "id" : "egt8nw5" + }, { + "label" : "Mandant bearbeiten", + "shortcut" : "", + "customClass" : "ml-4", + "persistent" : false, + "clearOnHide" : false, + "mask" : false, + "tableView" : true, + "alwaysEnabled" : false, + "type" : "checkbox", + "input" : true, + "key" : "edit_tenant", + "validate" : { + "unique" : false, + "customMessage" : "", + "json" : "", + "required" : false, + "custom" : "", + "customPrivate" : false + }, + "conditional" : { + "show" : "", + "when" : "", + "json" : "", + "eq" : "" + }, + "customConditional" : "show = data.wizard_selection == 'choose_tenant';", + "properties" : { }, + "tags" : [ ], + "defaultValue" : false, + "tabs" : null, + "reorder" : false, + "encrypted" : false, + "logic" : [ ], + "placeholder" : "", + "prefix" : "", + "suffix" : "", + "multiple" : false, + "protected" : false, + "unique" : false, + "hidden" : false, + "dataGridLabel" : true, + "labelPosition" : "right", + "labelWidth" : 30, + "labelMargin" : 3, + "description" : "", + "errorLabel" : "", + "tooltip" : "", + "hideLabel" : false, + "tabindex" : "", + "disabled" : false, + "autofocus" : false, + "dbIndex" : false, + "customDefaultValue" : "", + "calculateValue" : "", + "allowCalculateOverride" : false, + "widget" : null, + "refreshOn" : "", + "clearOnRefresh" : false, + "validateOn" : "change", + "inputType" : "checkbox", + "value" : "", + "name" : "", + "id" : "eq8u44o" + } ], + "input" : false, + "key" : "ChooseTenant", + "tags" : [ ], + "conditional" : { + "show" : "", + "when" : null, + "eq" : "" + }, + "properties" : { + "" : "" + }, + "placeholder" : "", + "prefix" : "", + "customClass" : "", + "suffix" : "", + "multiple" : false, + "defaultValue" : null, + "protected" : false, + "unique" : false, + "persistent" : false, + "hidden" : false, + "clearOnHide" : false, + "dataGridLabel" : false, + "labelWidth" : 30, + "labelMargin" : 3, + "description" : "", + "errorLabel" : "", + "tooltip" : "", + "hideLabel" : false, + "tabindex" : "", + "disabled" : false, + "autofocus" : false, + "dbIndex" : false, + "customDefaultValue" : "", + "calculateValue" : "", + "allowCalculateOverride" : false, + "widget" : null, + "refreshOn" : "", + "clearOnRefresh" : false, + "validateOn" : "change", + "validate" : { + "required" : false, + "custom" : "", + "customPrivate" : false + }, + "theme" : "default", + "breadcrumb" : "default", + "lazyLoad" : false, + "id" : "eqkhq0d" + }, { + "label" : "Mandant bearbeiten", + "title" : "Mandant bearbeiten", + "clearOnHide" : true, + "mask" : false, + "tableView" : false, + "type" : "panel", + "key" : "page2", + "input" : false, + "components" : [ { + "label" : "tenant", + "hideLabel" : true, + "mask" : false, + "tableView" : true, + "type" : "container", + "input" : true, + "key" : "tenant", + "components" : [ { + "labelPosition" : "left-left", + "columns" : [ { + "components" : [ { + "label" : "Name", + "labelPosition" : "left-left", + "allowMultipleMasks" : false, + "showWordCount" : false, + "showCharCount" : false, + "clearOnHide" : false, + "tableView" : true, + "alwaysEnabled" : false, + "type" : "textfield", + "input" : true, + "key" : "name", + "defaultValue" : "", + "validate" : { + "unique" : false, + "customMessage" : "Zeichenkette ohne Sonderzeichen, mindestens 4 und höchstens 15 Zeichen", + "json" : "", + "required" : true, + "minLength" : null, + "maxLength" : null, + "minWords" : null, + "maxWords" : null, + "pattern" : "^[ a-zA-Z]{4,15}$", + "custom" : "", + "customPrivate" : false + }, + "inputFormat" : "plain", + "properties" : { }, + "tags" : [ ], + "conditional" : { + "show" : "", + "when" : "", + "json" : "", + "eq" : "" + }, + "tabs" : null, + "encrypted" : false, + "customConditional" : "", + "logic" : [ ], + "widget" : { + "type" : "", + "format" : "yyyy-MM-dd hh:mm a", + "dateFormat" : "yyyy-MM-dd hh:mm a", + "saveAs" : "text" + }, + "reorder" : false, + "placeholder" : "", + "prefix" : "", + "customClass" : "", + "suffix" : "", + "multiple" : false, + "protected" : false, + "unique" : false, + "persistent" : true, + "hidden" : false, + "dataGridLabel" : false, + "labelWidth" : 30, + "labelMargin" : 3, + "description" : "", + "errorLabel" : "", + "tooltip" : "", + "hideLabel" : false, + "tabindex" : "", + "disabled" : false, + "autofocus" : false, + "dbIndex" : false, + "customDefaultValue" : "", + "calculateValue" : "", + "allowCalculateOverride" : false, + "refreshOn" : "", + "clearOnRefresh" : false, + "validateOn" : "change", + "mask" : false, + "inputType" : "text", + "inputMask" : "", + "id" : "ee19bke" + }, { + "label" : "Id", + "mask" : false, + "tableView" : true, + "type" : "hidden", + "input" : true, + "key" : "id", + "properties" : { }, + "tags" : [ ], + "placeholder" : "", + "prefix" : "", + "customClass" : "", + "suffix" : "", + "multiple" : false, + "defaultValue" : null, + "protected" : false, + "unique" : false, + "persistent" : true, + "hidden" : false, + "clearOnHide" : true, + "dataGridLabel" : false, + "labelPosition" : "top", + "labelWidth" : 30, + "labelMargin" : 3, + "description" : "", + "errorLabel" : "", + "tooltip" : "", + "hideLabel" : false, + "tabindex" : "", + "disabled" : false, + "autofocus" : false, + "dbIndex" : false, + "customDefaultValue" : "", + "calculateValue" : "", + "allowCalculateOverride" : false, + "widget" : null, + "refreshOn" : "", + "clearOnRefresh" : false, + "validateOn" : "change", + "validate" : { + "required" : false, + "custom" : "", + "customPrivate" : false + }, + "conditional" : { + "show" : null, + "when" : null, + "eq" : "" + }, + "inputType" : "hidden", + "id" : "e2ysnmg" + } ], + "width" : 6, + "offset" : 0, + "push" : 0, + "pull" : 0, + "type" : "column", + "input" : false, + "key" : "column1", + "tableView" : true, + "label" : "", + "clearOnHide" : false, + "hideOnChildrenHidden" : false, + "placeholder" : "", + "prefix" : "", + "customClass" : "", + "suffix" : "", + "multiple" : false, + "defaultValue" : null, + "protected" : false, + "unique" : false, + "persistent" : true, + "hidden" : false, + "dataGridLabel" : false, + "labelPosition" : "top", + "labelWidth" : 30, + "labelMargin" : 3, + "description" : "", + "errorLabel" : "", + "tooltip" : "", + "hideLabel" : false, + "tabindex" : "", + "disabled" : false, + "autofocus" : false, + "dbIndex" : false, + "customDefaultValue" : "", + "calculateValue" : "", + "allowCalculateOverride" : false, + "widget" : null, + "refreshOn" : "", + "clearOnRefresh" : false, + "validateOn" : "change", + "validate" : { + "required" : false, + "custom" : "", + "customPrivate" : false + }, + "conditional" : { + "show" : null, + "when" : null, + "eq" : "" + }, + "id" : "erubkto" + }, { + "components" : [ { + "label" : "Key", + "labelPosition" : "left-left", + "allowMultipleMasks" : false, + "showWordCount" : false, + "showCharCount" : false, + "tableView" : true, + "alwaysEnabled" : false, + "type" : "textfield", + "input" : true, + "key" : "key", + "defaultValue" : "", + "validate" : { + "customMessage" : "Zeichenkette ohne Sonderzeichen, mindestens 4 und höchstens 15 Zeichen", + "json" : "", + "required" : true, + "minLength" : null, + "maxLength" : null, + "minWords" : null, + "maxWords" : null, + "pattern" : "^[a-z]{4,15}$", + "custom" : "", + "customPrivate" : false + }, + "conditional" : { + "show" : "", + "when" : "", + "json" : "", + "eq" : "" + }, + "tabs" : null, + "properties" : { }, + "inputFormat" : "plain", + "encrypted" : false, + "tags" : null, + "customConditional" : "", + "logic" : [ ], + "widget" : { + "type" : "", + "format" : "yyyy-MM-dd hh:mm a", + "dateFormat" : "yyyy-MM-dd hh:mm a", + "saveAs" : "text" + }, + "reorder" : false, + "placeholder" : "", + "prefix" : "", + "customClass" : "", + "suffix" : "", + "multiple" : false, + "protected" : false, + "unique" : false, + "persistent" : true, + "hidden" : false, + "clearOnHide" : true, + "dataGridLabel" : false, + "labelWidth" : 30, + "labelMargin" : 3, + "description" : "", + "errorLabel" : "", + "tooltip" : "", + "hideLabel" : false, + "tabindex" : "", + "disabled" : false, + "autofocus" : false, + "dbIndex" : false, + "customDefaultValue" : "", + "calculateValue" : "", + "allowCalculateOverride" : false, + "refreshOn" : "", + "clearOnRefresh" : false, + "validateOn" : "change", + "mask" : false, + "inputType" : "text", + "inputMask" : "", + "id" : "een0aa" + } ], + "width" : 6, + "offset" : 0, + "push" : 0, + "pull" : 0, + "type" : "column", + "input" : false, + "key" : "column2", + "tableView" : true, + "label" : "", + "clearOnHide" : false, + "hideOnChildrenHidden" : false, + "placeholder" : "", + "prefix" : "", + "customClass" : "", + "suffix" : "", + "multiple" : false, + "defaultValue" : null, + "protected" : false, + "unique" : false, + "persistent" : true, + "hidden" : false, + "dataGridLabel" : false, + "labelPosition" : "top", + "labelWidth" : 30, + "labelMargin" : 3, + "description" : "", + "errorLabel" : "", + "tooltip" : "", + "hideLabel" : false, + "tabindex" : "", + "disabled" : false, + "autofocus" : false, + "dbIndex" : false, + "customDefaultValue" : "", + "calculateValue" : "", + "allowCalculateOverride" : false, + "widget" : null, + "refreshOn" : "", + "clearOnRefresh" : false, + "validateOn" : "change", + "validate" : { + "required" : false, + "custom" : "", + "customPrivate" : false + }, + "conditional" : { + "show" : null, + "when" : null, + "eq" : "" + }, + "id" : "eidse8e" + } ], + "label" : "Mengenrabattnr.", + "mask" : false, + "tableView" : false, + "type" : "columns", + "input" : false, + "key" : "columns", + "placeholder" : "", + "prefix" : "", + "customClass" : "", + "suffix" : "", + "multiple" : false, + "defaultValue" : null, + "protected" : false, + "unique" : false, + "persistent" : false, + "hidden" : false, + "clearOnHide" : false, + "dataGridLabel" : false, + "labelWidth" : 30, + "labelMargin" : 3, + "description" : "", + "errorLabel" : "", + "tooltip" : "", + "hideLabel" : false, + "tabindex" : "", + "disabled" : false, + "autofocus" : false, + "dbIndex" : false, + "customDefaultValue" : "", + "calculateValue" : "", + "allowCalculateOverride" : false, + "widget" : null, + "refreshOn" : "", + "clearOnRefresh" : false, + "validateOn" : "change", + "validate" : { + "required" : false, + "custom" : "", + "customPrivate" : false + }, + "conditional" : { + "show" : null, + "when" : null, + "eq" : "" + }, + "autoAdjust" : false, + "hideOnChildrenHidden" : false, + "id" : "ebom8zl" + } ], + "clearOnHide" : false, + "placeholder" : "", + "prefix" : "", + "customClass" : "", + "suffix" : "", + "multiple" : false, + "defaultValue" : null, + "protected" : false, + "unique" : false, + "persistent" : true, + "hidden" : false, + "dataGridLabel" : false, + "labelPosition" : "top", + "labelWidth" : 30, + "labelMargin" : 3, + "description" : "", + "errorLabel" : "", + "tooltip" : "", + "tabindex" : "", + "disabled" : false, + "autofocus" : false, + "dbIndex" : false, + "customDefaultValue" : "", + "calculateValue" : "", + "allowCalculateOverride" : false, + "widget" : null, + "refreshOn" : "", + "clearOnRefresh" : false, + "validateOn" : "change", + "validate" : { + "required" : false, + "custom" : "", + "customPrivate" : false + }, + "conditional" : { + "show" : null, + "when" : null, + "eq" : "" + }, + "tree" : true, + "id" : "e7k9du" + } ], + "conditional" : { + "show" : "", + "when" : "", + "json" : "", + "eq" : "" + }, + "customConditional" : "show = data.wizard_selection == 'choose_tenant' && !!data.edit_tenant && !!data.tenant && !!data.tenant.id;", + "placeholder" : "", + "prefix" : "", + "customClass" : "", + "suffix" : "", + "multiple" : false, + "defaultValue" : null, + "protected" : false, + "unique" : false, + "persistent" : false, + "hidden" : false, + "dataGridLabel" : false, + "labelPosition" : "top", + "labelWidth" : 30, + "labelMargin" : 3, + "description" : "", + "errorLabel" : "", + "tooltip" : "", + "hideLabel" : false, + "tabindex" : "", + "disabled" : false, + "autofocus" : false, + "dbIndex" : false, + "customDefaultValue" : "", + "calculateValue" : "", + "allowCalculateOverride" : false, + "widget" : null, + "refreshOn" : "", + "clearOnRefresh" : false, + "validateOn" : "change", + "validate" : { + "required" : false, + "custom" : "", + "customPrivate" : false + }, + "theme" : "default", + "breadcrumb" : "default", + "lazyLoad" : false, + "id" : "ewxh0sp" + }, { + "label" : "Mandant erfassen", + "title" : "Mandant erfassen", + "mask" : false, + "tableView" : false, + "type" : "panel", + "key" : "page2", + "input" : false, + "components" : [ { + "label" : "tenant", + "hideLabel" : true, + "mask" : false, + "tableView" : true, + "type" : "container", + "input" : true, + "key" : "tenant", + "components" : [ { + "labelPosition" : "left-left", + "columns" : [ { + "components" : [ { + "label" : "Name", + "labelPosition" : "left-left", + "allowMultipleMasks" : false, + "showWordCount" : false, + "showCharCount" : false, + "clearOnHide" : false, + "tableView" : true, + "alwaysEnabled" : false, + "type" : "textfield", + "input" : true, + "key" : "name", + "defaultValue" : "", + "validate" : { + "unique" : false, + "customMessage" : "Zeichenkette ohne Sonderzeichen, mindestens 4 und höchstens 15 Zeichen", + "json" : "", + "required" : true, + "minLength" : null, + "maxLength" : null, + "minWords" : null, + "maxWords" : null, + "pattern" : "^[ a-zA-Z]{4,15}$", + "custom" : "", + "customPrivate" : false + }, + "inputFormat" : "plain", + "properties" : { }, + "tags" : [ ], + "conditional" : { + "show" : "", + "when" : "", + "json" : "", + "eq" : "" + }, + "tabs" : null, + "encrypted" : false, + "customConditional" : "", + "logic" : [ ], + "widget" : { + "type" : "", + "format" : "yyyy-MM-dd hh:mm a", + "dateFormat" : "yyyy-MM-dd hh:mm a", + "saveAs" : "text" + }, + "reorder" : false, + "placeholder" : "", + "prefix" : "", + "customClass" : "", + "suffix" : "", + "multiple" : false, + "protected" : false, + "unique" : false, + "persistent" : true, + "hidden" : false, + "dataGridLabel" : false, + "labelWidth" : 30, + "labelMargin" : 3, + "description" : "", + "errorLabel" : "", + "tooltip" : "", + "hideLabel" : false, + "tabindex" : "", + "disabled" : false, + "autofocus" : false, + "dbIndex" : false, + "customDefaultValue" : "", + "calculateValue" : "", + "allowCalculateOverride" : false, + "refreshOn" : "", + "clearOnRefresh" : false, + "validateOn" : "change", + "mask" : false, + "inputType" : "text", + "inputMask" : "", + "id" : "ep5rkir" + } ], + "width" : 6, + "offset" : 0, + "push" : 0, + "pull" : 0, + "type" : "column", + "input" : false, + "key" : "column3", + "tableView" : true, + "label" : "", + "clearOnHide" : false, + "hideOnChildrenHidden" : false, + "placeholder" : "", + "prefix" : "", + "customClass" : "", + "suffix" : "", + "multiple" : false, + "defaultValue" : null, + "protected" : false, + "unique" : false, + "persistent" : true, + "hidden" : false, + "dataGridLabel" : false, + "labelPosition" : "top", + "labelWidth" : 30, + "labelMargin" : 3, + "description" : "", + "errorLabel" : "", + "tooltip" : "", + "hideLabel" : false, + "tabindex" : "", + "disabled" : false, + "autofocus" : false, + "dbIndex" : false, + "customDefaultValue" : "", + "calculateValue" : "", + "allowCalculateOverride" : false, + "widget" : null, + "refreshOn" : "", + "clearOnRefresh" : false, + "validateOn" : "change", + "validate" : { + "required" : false, + "custom" : "", + "customPrivate" : false + }, + "conditional" : { + "show" : null, + "when" : null, + "eq" : "" + }, + "id" : "e53ocje" + }, { + "components" : [ { + "label" : "Key", + "labelPosition" : "left-left", + "allowMultipleMasks" : false, + "showWordCount" : false, + "showCharCount" : false, + "tableView" : true, + "alwaysEnabled" : false, + "type" : "textfield", + "input" : true, + "key" : "key", + "defaultValue" : "", + "validate" : { + "customMessage" : "Zeichenkette ohne Sonderzeichen, mindestens 4 und höchstens 15 Zeichen", + "json" : "", + "required" : true, + "minLength" : null, + "maxLength" : null, + "minWords" : null, + "maxWords" : null, + "pattern" : "^[a-z]{4,15}$", + "custom" : "", + "customPrivate" : false + }, + "conditional" : { + "show" : "", + "when" : "", + "json" : "", + "eq" : "" + }, + "tabs" : null, + "properties" : { }, + "tags" : [ ], + "inputFormat" : "plain", + "encrypted" : false, + "customConditional" : "", + "logic" : [ ], + "widget" : { + "type" : "", + "format" : "yyyy-MM-dd hh:mm a", + "dateFormat" : "yyyy-MM-dd hh:mm a", + "saveAs" : "text" + }, + "reorder" : false, + "placeholder" : "", + "prefix" : "", + "customClass" : "", + "suffix" : "", + "multiple" : false, + "protected" : false, + "unique" : false, + "persistent" : true, + "hidden" : false, + "clearOnHide" : true, + "dataGridLabel" : false, + "labelWidth" : 30, + "labelMargin" : 3, + "description" : "", + "errorLabel" : "", + "tooltip" : "", + "hideLabel" : false, + "tabindex" : "", + "disabled" : false, + "autofocus" : false, + "dbIndex" : false, + "customDefaultValue" : "", + "calculateValue" : "", + "allowCalculateOverride" : false, + "refreshOn" : "", + "clearOnRefresh" : false, + "validateOn" : "change", + "mask" : false, + "inputType" : "text", + "inputMask" : "", + "id" : "ezyp65o" + } ], + "width" : 6, + "offset" : 0, + "push" : 0, + "pull" : 0, + "type" : "column", + "input" : false, + "key" : "column4", + "tableView" : true, + "label" : "", + "clearOnHide" : false, + "hideOnChildrenHidden" : false, + "placeholder" : "", + "prefix" : "", + "customClass" : "", + "suffix" : "", + "multiple" : false, + "defaultValue" : null, + "protected" : false, + "unique" : false, + "persistent" : true, + "hidden" : false, + "dataGridLabel" : false, + "labelPosition" : "top", + "labelWidth" : 30, + "labelMargin" : 3, + "description" : "", + "errorLabel" : "", + "tooltip" : "", + "hideLabel" : false, + "tabindex" : "", + "disabled" : false, + "autofocus" : false, + "dbIndex" : false, + "customDefaultValue" : "", + "calculateValue" : "", + "allowCalculateOverride" : false, + "widget" : null, + "refreshOn" : "", + "clearOnRefresh" : false, + "validateOn" : "change", + "validate" : { + "required" : false, + "custom" : "", + "customPrivate" : false + }, + "conditional" : { + "show" : null, + "when" : null, + "eq" : "" + }, + "id" : "exh1xre" + } ], + "label" : "Mengenrabattnr.", + "mask" : false, + "tableView" : false, + "type" : "columns", + "input" : false, + "key" : "columns", + "placeholder" : "", + "prefix" : "", + "customClass" : "", + "suffix" : "", + "multiple" : false, + "defaultValue" : null, + "protected" : false, + "unique" : false, + "persistent" : false, + "hidden" : false, + "clearOnHide" : false, + "dataGridLabel" : false, + "labelWidth" : 30, + "labelMargin" : 3, + "description" : "", + "errorLabel" : "", + "tooltip" : "", + "hideLabel" : false, + "tabindex" : "", + "disabled" : false, + "autofocus" : false, + "dbIndex" : false, + "customDefaultValue" : "", + "calculateValue" : "", + "allowCalculateOverride" : false, + "widget" : null, + "refreshOn" : "", + "clearOnRefresh" : false, + "validateOn" : "change", + "validate" : { + "required" : false, + "custom" : "", + "customPrivate" : false + }, + "conditional" : { + "show" : null, + "when" : null, + "eq" : "" + }, + "autoAdjust" : false, + "hideOnChildrenHidden" : false, + "id" : "eb8wo6f" + } ], + "clearOnHide" : false, + "placeholder" : "", + "prefix" : "", + "customClass" : "", + "suffix" : "", + "multiple" : false, + "defaultValue" : null, + "protected" : false, + "unique" : false, + "persistent" : true, + "hidden" : false, + "dataGridLabel" : false, + "labelPosition" : "top", + "labelWidth" : 30, + "labelMargin" : 3, + "description" : "", + "errorLabel" : "", + "tooltip" : "", + "tabindex" : "", + "disabled" : false, + "autofocus" : false, + "dbIndex" : false, + "customDefaultValue" : "", + "calculateValue" : "", + "allowCalculateOverride" : false, + "widget" : null, + "refreshOn" : "", + "clearOnRefresh" : false, + "validateOn" : "change", + "validate" : { + "required" : false, + "custom" : "", + "customPrivate" : false + }, + "conditional" : { + "show" : null, + "when" : null, + "eq" : "" + }, + "tree" : true, + "id" : "eazyhlh" + } ], + "conditional" : { + "show" : "", + "when" : "", + "json" : "", + "eq" : "" + }, + "customConditional" : "show = data.wizard_selection == 'create_new_tenant';", + "logic" : [ ], + "properties" : { }, + "tags" : [ ], + "placeholder" : "", + "prefix" : "", + "customClass" : "", + "suffix" : "", + "multiple" : false, + "defaultValue" : null, + "protected" : false, + "unique" : false, + "persistent" : false, + "hidden" : false, + "clearOnHide" : false, + "dataGridLabel" : false, + "labelPosition" : "top", + "labelWidth" : 30, + "labelMargin" : 3, + "description" : "", + "errorLabel" : "", + "tooltip" : "", + "hideLabel" : false, + "tabindex" : "", + "disabled" : false, + "autofocus" : false, + "dbIndex" : false, + "customDefaultValue" : "", + "calculateValue" : "", + "allowCalculateOverride" : false, + "widget" : null, + "refreshOn" : "", + "clearOnRefresh" : false, + "validateOn" : "change", + "validate" : { + "required" : false, + "custom" : "", + "customPrivate" : false + }, + "theme" : "default", + "breadcrumb" : "default", + "lazyLoad" : false, + "id" : "eknczn2" + } ] +} \ No newline at end of file diff --git a/smardigo/provisioning/form/simple-connect.json b/smardigo/provisioning/form/simple-connect.json new file mode 100644 index 0000000..90ffe6e --- /dev/null +++ b/smardigo/provisioning/form/simple-connect.json @@ -0,0 +1,653 @@ +{ + "name": "Simple Connect", + "configKey": "simple-connect", + "page": 0, + "components": [ + { + "label": "Cluster", + "mask": false, + "tableView": true, + "alwaysEnabled": false, + "type": "container", + "input": true, + "key": "cluster", + "validate": { + "customMessage": "", + "json": "", + "required": false, + "custom": "", + "customPrivate": false + }, + "conditional": { + "show": "", + "when": "", + "json": "", + "eq": "" + }, + "components": [ + { + "label": "Cluster", + "mask": false, + "tableView": true, + "alwaysEnabled": false, + "type": "well", + "input": false, + "key": "cluster", + "conditional": { + "show": "", + "when": "", + "json": "", + "eq": "" + }, + "components": [ + { + "label": "Stage", + "labelPosition": "left-left", + "allowMultipleMasks": false, + "showWordCount": false, + "showCharCount": false, + "disabled": true, + "tableView": true, + "alwaysEnabled": false, + "type": "textfield", + "input": true, + "key": "stage", + "defaultValue": "", + "validate": { + "customMessage": "", + "json": "", + "required": true, + "minLength": null, + "maxLength": null, + "minWords": null, + "maxWords": null, + "custom": "", + "customPrivate": false, + "pattern": "" + }, + "conditional": { + "show": "", + "when": "", + "json": "", + "eq": "" + }, + "tabs": null, + "inputFormat": "plain", + "encrypted": false, + "properties": { + }, + "tags": [ + ], + "customConditional": "", + "logic": [ + ], + "widget": { + "type": "", + "format": "yyyy-MM-dd hh:mm a", + "dateFormat": "yyyy-MM-dd hh:mm a", + "saveAs": "text" + }, + "reorder": false, + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "dataGridLabel": false, + "labelWidth": 30, + "labelMargin": 3, + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "allowCalculateOverride": false, + "refreshOn": "", + "clearOnRefresh": false, + "validateOn": "change", + "mask": false, + "inputType": "text", + "inputMask": "", + "id": "ew5yzbt" + }, + { + "label": "Name", + "labelPosition": "left-left", + "allowMultipleMasks": false, + "showWordCount": false, + "showCharCount": false, + "tableView": true, + "alwaysEnabled": false, + "type": "textfield", + "input": true, + "key": "name", + "defaultValue": "", + "validate": { + "customMessage": "", + "json": "", + "required": true, + "minLength": null, + "maxLength": null, + "minWords": null, + "maxWords": null, + "custom": "", + "customPrivate": false, + "pattern": "" + }, + "conditional": { + "show": "", + "when": "", + "json": "", + "eq": "" + }, + "tabs": null, + "inputFormat": "plain", + "encrypted": false, + "properties": { + }, + "tags": [ + ], + "customConditional": "", + "logic": [ + ], + "widget": { + "type": "", + "format": "yyyy-MM-dd hh:mm a", + "dateFormat": "yyyy-MM-dd hh:mm a", + "saveAs": "text" + }, + "reorder": false, + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "dataGridLabel": false, + "labelWidth": 30, + "labelMargin": 3, + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "allowCalculateOverride": false, + "refreshOn": "", + "clearOnRefresh": false, + "validateOn": "change", + "mask": false, + "inputType": "text", + "inputMask": "", + "id": "egdtruh" + }, + { + "label": "Size", + "labelPosition": "left-left", + "mask": false, + "disabled": true, + "tableView": true, + "alwaysEnabled": false, + "type": "number", + "input": true, + "key": "size", + "validate": { + "customMessage": "", + "json": "", + "required": true, + "min": null, + "max": null, + "custom": "", + "customPrivate": false, + "step": "any", + "integer": "" + }, + "conditional": { + "show": "", + "when": "", + "json": "", + "eq": "" + }, + "tabs": null, + "properties": { + }, + "tags": [ + ], + "delimiter": false, + "requireDecimal": false, + "encrypted": false, + "decimalLimit": null, + "customConditional": "", + "logic": [ + ], + "reorder": false, + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "defaultValue": null, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "dataGridLabel": false, + "labelWidth": 30, + "labelMargin": 3, + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "allowCalculateOverride": false, + "widget": null, + "refreshOn": "", + "clearOnRefresh": false, + "validateOn": "change", + "id": "e33y58" + }, + { + "label": "Service", + "labelPosition": "left-left", + "allowMultipleMasks": false, + "showWordCount": false, + "showCharCount": false, + "disabled": true, + "tableView": true, + "alwaysEnabled": false, + "type": "textfield", + "input": true, + "key": "service", + "defaultValue": "", + "validate": { + "customMessage": "", + "json": "", + "required": true, + "minLength": null, + "maxLength": null, + "minWords": null, + "maxWords": null, + "custom": "", + "customPrivate": false, + "pattern": "" + }, + "conditional": { + "show": "", + "when": "", + "json": "", + "eq": "" + }, + "tabs": null, + "inputFormat": "plain", + "encrypted": false, + "properties": { + }, + "tags": [ + ], + "customConditional": "", + "logic": [ + ], + "widget": { + "type": "", + "format": "yyyy-MM-dd hh:mm a", + "dateFormat": "yyyy-MM-dd hh:mm a", + "saveAs": "text" + }, + "reorder": false, + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "dataGridLabel": false, + "labelWidth": 30, + "labelMargin": 3, + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "allowCalculateOverride": false, + "refreshOn": "", + "clearOnRefresh": false, + "validateOn": "change", + "mask": false, + "inputType": "text", + "inputMask": "", + "id": "eu0zrp9" + } + ], + "tabs": null, + "reorder": false, + "properties": { + }, + "tags": null, + "customConditional": "", + "logic": [ + ], + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "defaultValue": null, + "protected": false, + "unique": false, + "persistent": false, + "hidden": false, + "clearOnHide": true, + "dataGridLabel": false, + "labelPosition": "top", + "labelWidth": 30, + "labelMargin": 3, + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "allowCalculateOverride": false, + "widget": null, + "refreshOn": "", + "clearOnRefresh": false, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false + }, + "id": "e60dk9" + } + ], + "tabs": null, + "encrypted": false, + "properties": { + }, + "tags": [ + ], + "customConditional": "", + "logic": [ + ], + "reorder": false, + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "defaultValue": null, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "dataGridLabel": false, + "labelPosition": "top", + "labelWidth": 30, + "labelMargin": 3, + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "allowCalculateOverride": false, + "widget": null, + "refreshOn": "", + "clearOnRefresh": false, + "validateOn": "change", + "tree": true, + "id": "eu5stp" + }, + { + "label": "progress_current", + "labelPosition": "left-left", + "hidden": true, + "mask": false, + "tableView": true, + "alwaysEnabled": false, + "type": "number", + "input": true, + "key": "progress_current", + "validate": { + "customMessage": "", + "json": "", + "required": false, + "custom": "", + "customPrivate": false, + "min": "", + "max": "", + "step": "any", + "integer": "" + }, + "conditional": { + "show": "", + "when": "", + "json": "", + "eq": "" + }, + "tabs": null, + "delimiter": false, + "requireDecimal": false, + "encrypted": false, + "properties": { + }, + "tags": [ + ], + "decimalLimit": null, + "customConditional": "", + "logic": [ + ], + "reorder": false, + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "defaultValue": null, + "protected": false, + "unique": false, + "persistent": true, + "clearOnHide": true, + "dataGridLabel": false, + "labelWidth": 30, + "labelMargin": 3, + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "allowCalculateOverride": false, + "widget": null, + "refreshOn": "", + "clearOnRefresh": false, + "validateOn": "change", + "id": "exepewd" + }, + { + "label": "progress_max", + "labelPosition": "left-left", + "hidden": true, + "mask": false, + "tableView": true, + "alwaysEnabled": false, + "type": "number", + "input": true, + "key": "progress_max", + "validate": { + "customMessage": "", + "json": "", + "required": false, + "custom": "", + "customPrivate": false, + "min": "", + "max": "", + "step": "any", + "integer": "" + }, + "conditional": { + "show": "", + "when": "", + "json": "", + "eq": "" + }, + "tabs": null, + "delimiter": false, + "requireDecimal": false, + "encrypted": false, + "decimalLimit": null, + "properties": { + }, + "tags": [ + ], + "customConditional": "", + "logic": [ + ], + "reorder": false, + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "defaultValue": null, + "protected": false, + "unique": false, + "persistent": true, + "clearOnHide": true, + "dataGridLabel": false, + "labelWidth": 30, + "labelMargin": 3, + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "allowCalculateOverride": false, + "widget": null, + "refreshOn": "", + "clearOnRefresh": false, + "validateOn": "change", + "id": "eyaf4fl" + }, + { + "label": "HTML", + "labelPosition": "left-left", + "className": "", + "attrs": [ + { + "attr": "", + "value": "" + } + ], + "content": "
\n
\n
", + "refreshOnChange": true, + "mask": false, + "tableView": true, + "alwaysEnabled": false, + "type": "htmlelement", + "input": false, + "key": "html", + "validate": { + "customMessage": "", + "json": "", + "required": false, + "custom": "", + "customPrivate": false + }, + "conditional": { + "show": "", + "when": "", + "json": "", + "eq": "" + }, + "tabs": null, + "encrypted": false, + "properties": { + }, + "tags": null, + "customConditional": "", + "logic": [ + ], + "refreshOn": "data", + "reorder": false, + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "defaultValue": null, + "protected": false, + "unique": false, + "persistent": false, + "hidden": false, + "clearOnHide": true, + "dataGridLabel": false, + "labelWidth": 30, + "labelMargin": 3, + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "allowCalculateOverride": false, + "widget": null, + "clearOnRefresh": false, + "validateOn": "change", + "tag": "p", + "id": "e8dfoz" + } + ] +} diff --git a/smardigo/provisioning/form/tenant.json b/smardigo/provisioning/form/tenant.json new file mode 100644 index 0000000..bb0fa15 --- /dev/null +++ b/smardigo/provisioning/form/tenant.json @@ -0,0 +1,423 @@ +{ + "name" : "Mandnat", + "configKey" : "tenant", + "page" : 0, + "components" : [ { + "label" : "Mandant", + "mask" : false, + "tableView" : true, + "alwaysEnabled" : false, + "type" : "datasourcecontainer", + "input" : true, + "key" : "tenant", + "defaultValue" : { + "tenant" : { + "account_id" : "", + "id" : "", + "name" : "" + } + }, + "validate" : { + "customMessage" : "", + "json" : "", + "required" : false, + "custom" : "", + "customPrivate" : false + }, + "conditional" : { + "show" : "", + "when" : "", + "json" : "", + "eq" : "" + }, + "data" : { + "url" : "http://localhost:8080/api/v1/scopes/{{context.scopeId}}/tags/{{context.scopeTag}}/datasources/tenants/query?id={{data.tenant_id}}", + "method" : "GET", + "values" : [ { } ] + }, + "components" : [ { + "label" : "Mandant", + "hideLabel" : true, + "mask" : false, + "tableView" : true, + "alwaysEnabled" : false, + "type" : "container", + "input" : true, + "key" : "tenant", + "validate" : { + "customMessage" : "", + "json" : "", + "required" : false, + "custom" : "", + "customPrivate" : false + }, + "conditional" : { + "show" : "", + "when" : "", + "json" : "", + "eq" : "" + }, + "components" : [ { + "label" : "Mandant", + "mask" : false, + "tableView" : true, + "alwaysEnabled" : false, + "type" : "well", + "input" : false, + "key" : "tenant", + "conditional" : { + "show" : "", + "when" : "", + "json" : "", + "eq" : "" + }, + "components" : [ { + "label" : "Id", + "labelPosition" : "left-left", + "allowMultipleMasks" : false, + "showWordCount" : false, + "showCharCount" : false, + "tableView" : true, + "alwaysEnabled" : false, + "type" : "textfield", + "input" : true, + "key" : "id", + "defaultValue" : "", + "validate" : { + "customMessage" : "", + "json" : "", + "required" : false, + "custom" : "", + "customPrivate" : false, + "minLength" : "", + "maxLength" : "", + "minWords" : "", + "maxWords" : "", + "pattern" : "" + }, + "conditional" : { + "show" : "", + "when" : "", + "json" : "", + "eq" : "" + }, + "tabs" : null, + "properties" : { }, + "inputFormat" : "plain", + "encrypted" : false, + "tags" : null, + "customConditional" : "", + "logic" : [ ], + "widget" : { + "type" : "", + "format" : "yyyy-MM-dd hh:mm a", + "dateFormat" : "yyyy-MM-dd hh:mm a", + "saveAs" : "text" + }, + "reorder" : false, + "placeholder" : "", + "prefix" : "", + "customClass" : "", + "suffix" : "", + "multiple" : false, + "protected" : false, + "unique" : false, + "persistent" : true, + "hidden" : false, + "clearOnHide" : true, + "dataGridLabel" : false, + "labelWidth" : 30, + "labelMargin" : 3, + "description" : "", + "errorLabel" : "", + "tooltip" : "", + "hideLabel" : false, + "tabindex" : "", + "disabled" : false, + "autofocus" : false, + "dbIndex" : false, + "customDefaultValue" : "", + "calculateValue" : "", + "allowCalculateOverride" : false, + "refreshOn" : "", + "clearOnRefresh" : false, + "validateOn" : "change", + "mask" : false, + "inputType" : "text", + "inputMask" : "", + "id" : "e96sc1h" + }, { + "label" : "Name", + "labelPosition" : "left-left", + "allowMultipleMasks" : false, + "showWordCount" : false, + "showCharCount" : false, + "tableView" : true, + "alwaysEnabled" : false, + "type" : "textfield", + "input" : true, + "key" : "name", + "properties" : { }, + "tags" : [ ], + "defaultValue" : "", + "validate" : { + "customMessage" : "", + "json" : "", + "required" : false, + "custom" : "", + "customPrivate" : false, + "minLength" : "", + "maxLength" : "", + "minWords" : "", + "maxWords" : "", + "pattern" : "" + }, + "conditional" : { + "show" : "", + "when" : "", + "json" : "", + "eq" : "" + }, + "tabs" : null, + "inputFormat" : "plain", + "encrypted" : false, + "customConditional" : "", + "logic" : [ ], + "widget" : { + "type" : "", + "format" : "yyyy-MM-dd hh:mm a", + "dateFormat" : "yyyy-MM-dd hh:mm a", + "saveAs" : "text" + }, + "reorder" : false, + "placeholder" : "", + "prefix" : "", + "customClass" : "", + "suffix" : "", + "multiple" : false, + "protected" : false, + "unique" : false, + "persistent" : true, + "hidden" : false, + "clearOnHide" : true, + "dataGridLabel" : false, + "labelWidth" : 30, + "labelMargin" : 3, + "description" : "", + "errorLabel" : "", + "tooltip" : "", + "hideLabel" : false, + "tabindex" : "", + "disabled" : false, + "autofocus" : false, + "dbIndex" : false, + "customDefaultValue" : "", + "calculateValue" : "", + "allowCalculateOverride" : false, + "refreshOn" : "", + "clearOnRefresh" : false, + "validateOn" : "change", + "mask" : false, + "inputType" : "text", + "inputMask" : "", + "id" : "eyvg1sy" + }, { + "label" : "Key", + "labelPosition" : "left-left", + "allowMultipleMasks" : false, + "showWordCount" : false, + "showCharCount" : false, + "tableView" : true, + "alwaysEnabled" : false, + "type" : "textfield", + "input" : true, + "key" : "key", + "defaultValue" : "", + "validate" : { + "customMessage" : "", + "json" : "", + "required" : false, + "custom" : "", + "customPrivate" : false, + "minLength" : "", + "maxLength" : "", + "minWords" : "", + "maxWords" : "", + "pattern" : "" + }, + "conditional" : { + "show" : "", + "when" : "", + "json" : "", + "eq" : "" + }, + "tabs" : null, + "widget" : { + "type" : "", + "format" : "yyyy-MM-dd hh:mm a", + "dateFormat" : "yyyy-MM-dd hh:mm a", + "saveAs" : "text" + }, + "properties" : { }, + "reorder" : false, + "inputFormat" : "plain", + "encrypted" : false, + "tags" : null, + "customConditional" : "", + "logic" : [ ], + "placeholder" : "", + "prefix" : "", + "customClass" : "", + "suffix" : "", + "multiple" : false, + "protected" : false, + "unique" : false, + "persistent" : true, + "hidden" : false, + "clearOnHide" : true, + "dataGridLabel" : false, + "labelWidth" : 30, + "labelMargin" : 3, + "description" : "", + "errorLabel" : "", + "tooltip" : "", + "hideLabel" : false, + "tabindex" : "", + "disabled" : false, + "autofocus" : false, + "dbIndex" : false, + "customDefaultValue" : "", + "calculateValue" : "", + "allowCalculateOverride" : false, + "refreshOn" : "", + "clearOnRefresh" : false, + "validateOn" : "change", + "mask" : false, + "inputType" : "text", + "inputMask" : "", + "id" : "erag6o" + } ], + "tabs" : null, + "properties" : { }, + "tags" : [ ], + "reorder" : false, + "customConditional" : "", + "logic" : [ ], + "placeholder" : "", + "prefix" : "", + "customClass" : "", + "suffix" : "", + "multiple" : false, + "defaultValue" : null, + "protected" : false, + "unique" : false, + "persistent" : false, + "hidden" : false, + "clearOnHide" : true, + "dataGridLabel" : false, + "labelPosition" : "top", + "labelWidth" : 30, + "labelMargin" : 3, + "description" : "", + "errorLabel" : "", + "tooltip" : "", + "hideLabel" : false, + "tabindex" : "", + "disabled" : false, + "autofocus" : false, + "dbIndex" : false, + "customDefaultValue" : "", + "calculateValue" : "", + "allowCalculateOverride" : false, + "widget" : null, + "refreshOn" : "", + "clearOnRefresh" : false, + "validateOn" : "change", + "validate" : { + "required" : false, + "custom" : "", + "customPrivate" : false + }, + "id" : "ethzgw6" + } ], + "tabs" : null, + "properties" : { }, + "tags" : [ ], + "encrypted" : false, + "customConditional" : "", + "logic" : [ ], + "reorder" : false, + "placeholder" : "", + "prefix" : "", + "customClass" : "", + "suffix" : "", + "multiple" : false, + "defaultValue" : null, + "protected" : false, + "unique" : false, + "persistent" : true, + "hidden" : false, + "clearOnHide" : true, + "dataGridLabel" : false, + "labelPosition" : "top", + "labelWidth" : 30, + "labelMargin" : 3, + "description" : "", + "errorLabel" : "", + "tooltip" : "", + "tabindex" : "", + "disabled" : false, + "autofocus" : false, + "dbIndex" : false, + "customDefaultValue" : "", + "calculateValue" : "", + "allowCalculateOverride" : false, + "widget" : null, + "refreshOn" : "", + "clearOnRefresh" : false, + "validateOn" : "change", + "tree" : true, + "id" : "eqqtn1v" + } ], + "tabs" : null, + "properties" : { }, + "datapath" : "0", + "encrypted" : false, + "tags" : [ ], + "customConditional" : "", + "logic" : [ ], + "reorder" : false, + "placeholder" : "", + "prefix" : "", + "customClass" : "", + "suffix" : "", + "multiple" : false, + "protected" : false, + "unique" : false, + "persistent" : true, + "hidden" : false, + "clearOnHide" : true, + "dataGridLabel" : false, + "labelPosition" : "top", + "labelWidth" : 30, + "labelMargin" : 3, + "description" : "", + "errorLabel" : "", + "tooltip" : "", + "hideLabel" : false, + "tabindex" : "", + "disabled" : false, + "autofocus" : false, + "dbIndex" : false, + "customDefaultValue" : "", + "calculateValue" : "", + "allowCalculateOverride" : false, + "widget" : null, + "refreshOn" : "", + "clearOnRefresh" : false, + "validateOn" : "change", + "dataSrc" : "url", + "tree" : true, + "id" : "er4h7mh" + } ] +} \ No newline at end of file diff --git a/smardigo/provisioning/layout/simple-connect.json b/smardigo/provisioning/layout/simple-connect.json new file mode 100644 index 0000000..f790299 --- /dev/null +++ b/smardigo/provisioning/layout/simple-connect.json @@ -0,0 +1,83 @@ +{ + "name" : "simple-connect", + "configKey" : "simple-connect", + "tabExpression" : "{{ data.cluster.stage }}-{{ data.tenant.name }}-{{ data.cluster.name }}", + "readonlyExpression" : "data.vorgang_status > 10", + "components" : [ { + "type" : "columns", + "key" : "dossier", + "columns" : [ { + "components" : [ { + "type" : "form", + "key" : "header", + "readonlyExpression" : "true" + }, { + "type" : "html", + "content" : "
" + }, { + "type" : "columns", + "key" : "first-column", + "columns" : [ { + "components" : [ { + "type" : "page", + "key" : "dossier-page", + "toc" : "left", + "sections" : [ { + "type" : "section", + "key" : "master-data", + "title" : "Stammdaten", + "components" : [ { + "type" : "form", + "key" : "tenant", + "readonlyExpression" : "true" + } ] + }, { + "type" : "section", + "key" : "smardigo", + "title" : "Smardigo", + "components" : [ { + "type" : "form", + "key" : "simple-connect" + } ] + }, { + "type" : "section", + "key" : "dossier-attachments", + "title" : "Anhänge", + "components" : [ { + "type" : "form", + "key" : "attachments" + } ] + }, { + "type" : "section", + "key" : "dossier-comments", + "title" : "Kommentare", + "components" : [ { + "type" : "comments", + "key" : "comments" + } ] + }, { + "type" : "section", + "key" : "dossier-history", + "title" : "Protokoll", + "components" : [ { + "type" : "history", + "key" : "history" + } ] + } ] + } ], + "width" : "9" + }, { + "components" : [ { + "type" : "help-text", + "key" : "help-text" + }, { + "type" : "action-list", + "key" : "action-list" + } ], + "width" : "350px" + } ] + } ], + "width" : "12" + } ] + } ] +} \ No newline at end of file diff --git a/smardigo/provisioning/meta.info b/smardigo/provisioning/meta.info new file mode 100644 index 0000000..98c600c --- /dev/null +++ b/smardigo/provisioning/meta.info @@ -0,0 +1 @@ +scopeId=provisioning \ No newline at end of file diff --git a/smardigo/provisioning/policy/policy.json b/smardigo/provisioning/policy/policy.json new file mode 100644 index 0000000..4374fd7 --- /dev/null +++ b/smardigo/provisioning/policy/policy.json @@ -0,0 +1,13 @@ +{ + "configKey" : "policy", + "configType" : "policy", + "name" : "Policies", + "policies" : [ { + "id" : "read_write_all", + "name" : "Read/Write all", + "effect" : "allow", + "actions" : [ "read", "write" ], + "resources" : [ "variables:simple-connect:*" ], + "conditions" : [ ] + } ] +} \ No newline at end of file diff --git a/smardigo/provisioning/process-search/simple-connect-fallback.json b/smardigo/provisioning/process-search/simple-connect-fallback.json new file mode 100644 index 0000000..e1fa601 --- /dev/null +++ b/smardigo/provisioning/process-search/simple-connect-fallback.json @@ -0,0 +1,8 @@ +{ + "name" : "Simple Connect", + "configKey" : "simple-connect-fallback", + "processDefinitionKey" : "simple-connect", + "columns" : [ ], + "sorts" : [ ], + "filters" : [ ] +} \ No newline at end of file diff --git a/smardigo/provisioning/process-search/simple-connect.json b/smardigo/provisioning/process-search/simple-connect.json new file mode 100644 index 0000000..23b7ca4 --- /dev/null +++ b/smardigo/provisioning/process-search/simple-connect.json @@ -0,0 +1,68 @@ +{ + "name": "Simple Connect", + "configKey": "simple-connect", + "processDefinitionKey": "simple-connect", + "columns": [ + { + "key": "id", + "name": "ID", + "width": 50, + "hidden": true + }, + { + "key": "process_definition_key", + "name": "Prozess", + "width": 100, + "hidden": true + }, + { + "key": "creation_date", + "name": "Erstelldatum", + "width": 100 + }, + { + "key": "tenant.name", + "name": "Mandant Name", + "width": 100 + }, + { + "key": "tenant.key", + "name": "Mandant Schlüssel", + "width": 100 + }, + { + "key": "creation_user_id", + "name": "Ersteller", + "width": 150 + }, + { + "key": "vorgang_status_text", + "name": "Status", + "width": 100 + }, + { + "key": "candidateGroups", + "name": "Gruppen", + "width": 100, + "hidden": true + } + ], + "filters": [ + { + "name": "Creation User", + "key": "creation_user_id", + "defaultOption": { + "key": "default", + "name": "All" + } + }, + { + "name": "State", + "key": "process_state_text", + "defaultOption": { + "key": "default", + "name": "All" + } + } + ] +} diff --git a/smardigo/provisioning/process-variable-declaration/simple-connect.json b/smardigo/provisioning/process-variable-declaration/simple-connect.json new file mode 100644 index 0000000..ba9c893 --- /dev/null +++ b/smardigo/provisioning/process-variable-declaration/simple-connect.json @@ -0,0 +1,43 @@ +{ + "name" : "Simple Connect", + "configKey" : "simple-connect", + "configType" : "process-variable-declaration", + "variableDeclarations" : { + "antrag_decission" : { + "type" : "string", + "classification" : "PRIVATE" + }, + "cluster" : { + "type" : "object", + "classification" : "PRIVATE" + }, + "creation_date" : { + "type" : "date", + "classification" : "PRIVATE" + }, + "creation_user_id" : { + "type" : "userId", + "classification" : "PRIVATE" + }, + "edit_tenant" : { + "type" : "boolean", + "classification" : "PRIVATE" + }, + "progress_current" : { + "type" : "long", + "classification" : "PRIVATE" + }, + "progress_max" : { + "type" : "long", + "classification" : "PRIVATE" + }, + "tenant" : { + "type" : "object", + "classification" : "PRIVATE" + }, + "wizard_selection" : { + "type" : "string", + "classification" : "PRIVATE" + } + } +} \ No newline at end of file diff --git a/smardigo/provisioning/process/investigator.dmn b/smardigo/provisioning/process/investigator.dmn new file mode 100644 index 0000000..e50a91c --- /dev/null +++ b/smardigo/provisioning/process/investigator.dmn @@ -0,0 +1,28 @@ + + + + + + + tenant_id + + + + + + - + + + "head" + + + + + + + + + + + + diff --git a/smardigo/provisioning/process/simple-connect.bpmn b/smardigo/provisioning/process/simple-connect.bpmn new file mode 100644 index 0000000..743342f --- /dev/null +++ b/smardigo/provisioning/process/simple-connect.bpmn @@ -0,0 +1,968 @@ + + + + + + + + + + Flow_1bvsxg3 + + + + Flow_0xsem7d + + + + + + ${91} + Antrag abgebrochen + + + Flow_0xsem7d + Flow_0fqbjt7 + + + Flow_0fqbjt7 + Flow_1x24mk0 + + + + Flow_1x24mk0 + + + + Flow_1rtcnw8 + + + Flow_1bvsxg3 + + Flow_029ts9n + + + Flow_029ts9n + + + + + + + + + + + + + + Flow_17rbwn1 + Flow_13jykf9 + Flow_1hsqawc + + + + + ${15} + Antrag gesendet + + + Flow_1hsqawc + Flow_0ex5zxa + + + Flow_0ex5zxa + Flow_0zcb7z2 + Flow_0ki8zi3 + Flow_19if6oq + + + + + ${tenant.id} + + + Flow_0zcb7z2 + Flow_1y5ddsi + + + + + + import de.tolina.connect.common.variable.Variables +def authenticatedUserId = users.currentUserId() +Variables.userId(authenticatedUserId) + + + + Flow_1y5ddsi + Flow_0jdr8ms + Flow_1sqrzau + + + Flow_1sqrzau + Flow_1lmopkj + + + Flow_1lmopkj + Flow_1vbvp2f + Flow_0jdr8ms + + + Flow_1vbvp2f + Flow_0m834s1 + Flow_1cvz8xm + + + + + ${30} + Antrag freigegeben + + + Flow_1cvz8xm + Flow_1w2pl97 + + + Flow_0m834s1 + + + + ${$action == 'senden'} + + + + + + + + + + ${$action == 'abbrechen'} + + + + + + + ${$action == 'abbrechen'} + + + + + ${$action == 'speichern'} + + + ${antrag_decission== 'antragAblehnen'} + + + ${antrag_decission== 'antragGenehmigen'} + + + + Flow_0dybqr7 + Flow_17rbwn1 + + + + + + ${10} + Neu + + + Flow_1gqgiz8 + Flow_0dybqr7 + + + + + ${tenant.id} + + + Flow_0btq5mg + Flow_1gqgiz8 + + + + + ${0} + ${1} + + + dev + + ${1} + connect + + + + + Flow_1rtcnw8 + Flow_0btq5mg + + + Flow_0jynsyw + + + + Flow_0jynsyw + + + + + + + + + ${5} + + + Flow_1f0iyrk + Flow_11k5c1y + + + + + + import de.tolina.connect.common.variable.Variables +def authenticatedUserId = users.currentUserId() +Variables.userId(authenticatedUserId) + + + + Flow_15fkmn4 + + + + + ${50} + Service gestartet + + + Flow_11k5c1y + Flow_1ebhrqm + Flow_15fkmn4 + + + + + + import de.tolina.connect.common.variable.Variables +def authenticatedUserId = users.currentUserId() +Variables.userId(authenticatedUserId) + + + + Flow_1ebhrqm + Flow_1pwn0n9 + + + Flow_1pwn0n9 + + + + + + + + + + ${2} + + + Flow_11ki58f + Flow_1eku1o4 + + + + + + + + + ${3} + + + Flow_1eku1o4 + Flow_0pvr263 + + + + + + + + + ${4} + + + Flow_0pvr263 + Flow_1f0iyrk + + + + + ${1} + ${5} + + + Flow_0bzl5jh + Flow_11ki58f + + + + + + + + + + + + Flow_1w2pl97 + Flow_1myfmc6 + Flow_1onhxkb + + + + + + ${40} + Service wird gestartet + + + Flow_1myfmc6 + Flow_0bzl5jh + + + + + Flow_0ki8zi3 + + + + Flow_13jykf9 + + + + Flow_1onhxkb + + + + + + + + + Neuer Antrag für ${tenant.name} + ${cluster.stage}-${tenant.key}-${cluster.name} for ${cluster.service} + https://img.welt.de/img/vermischtes/bilder-des-tages/mobile207066931/1242503207-ci102l-w1024/Coronavirus-USA.jpg + + + + + Flow_19if6oq + Flow_0lrfzsu + + + + + + + + ${section} + + + + + Flow_0lrfzsu + Flow_1jfvhvl + + + + + + + MessageCard + http://schema.org/extensions + 0076D7 + Neuer Antrag für ${tenant.name} + ${sections} + + + + + Flow_1jfvhvl + Flow_0cxiaxt + + + Flow_0cxiaxt + + + Service auf Server installieren + + +- Domain (Services) +- connect +- (wordpress) + + + Shared Service +Server bei Hetzner erstellen + +- Provisioning +- Domain (Administration) +- Networks +- Monitoring +- Logging + + + Shared Service +Datenbanken erstellen + +- connect +- (wordpress) +- Credentials in Vorgang ablegen + + + Shared Service +Keycloak Realm mit Administrator Account + +- Neuer Nutzer (connect-admin) +- Emailadresse des Erstellers +- Automatisch generiertes PW +- PW per EMail an Administrator + + + + + + + + + + + + + + + + + + + + + + Neue Aufgabe + ${ansibleCommand} + https://img.welt.de/img/vermischtes/bilder-des-tages/mobile207066931/1242503207-ci102l-w1024/Coronavirus-USA.jpg + + + + + Flow_01qpec5 + Flow_0jp0wmd + + + + + + + ${section} + + + + + Flow_0jp0wmd + Flow_0m4h584 + + + + + + + MessageCard + http://schema.org/extensions + 0076D7 + Neue Aufgabe: ${comment} + ${sections} + + + + + Flow_0m4h584 + Flow_14vrrra + + + + + + + + + + + + + Flow_13nom3k + + + Flow_13nom3k + Flow_01qpec5 + + + Flow_14vrrra + Flow_0gcsmj7 + + + + + Flow_0gcsmj7 + Flow_1ju13h8 + + + Flow_1ju13h8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/smardigo/provisioning/role-policy-mapping/role-policy-mapping.json b/smardigo/provisioning/role-policy-mapping/role-policy-mapping.json new file mode 100644 index 0000000..8d590a4 --- /dev/null +++ b/smardigo/provisioning/role-policy-mapping/role-policy-mapping.json @@ -0,0 +1,8 @@ +{ + "name" : "Policy Mapping", + "configKey" : "role-policy-mapping", + "configType" : "role-policy-mapping", + "rolePolicyMapping" : { + "user" : [ "read_write_all" ] + } +} \ No newline at end of file diff --git a/smardigo/provisioning/script/ansible-end.groovy b/smardigo/provisioning/script/ansible-end.groovy new file mode 100644 index 0000000..e08ddf8 --- /dev/null +++ b/smardigo/provisioning/script/ansible-end.groovy @@ -0,0 +1 @@ +processes.byId(contextScopeId, contextProcessId).createComment(comment + ' beendet') \ No newline at end of file diff --git a/smardigo/provisioning/script/ansible-start.groovy b/smardigo/provisioning/script/ansible-start.groovy new file mode 100644 index 0000000..953e81f --- /dev/null +++ b/smardigo/provisioning/script/ansible-start.groovy @@ -0,0 +1,24 @@ +def env = [ + scope_id: contextScopeId, + process_instance_id: execution.getProcessInstanceId(), + smardigo_management_action: smardigoManagementAction, + cluster_name: tenant.key + '-' + cluster.name, + cluster_service: cluster.service, + cluster_size: cluster.size, + stage: cluster.stage, + current_realm_name: tenant.key, + current_realm_display_name: tenant.name +] + +def ansibleCommand= 'ansible-playbook ' + smardigoManagementAction + '.yml --vault-password-file ~/vault-pass' +def ansibleEnvironment= ' -e \"' +env.each { key, val -> + ansibleEnvironment+= key + '=\'' + val + '\' ' +} +ansibleEnvironment+= '\"' +ansibleCommand += ansibleEnvironment + +processes.byId(contextScopeId, contextProcessId).createComment(comment + ' gestartet') +processes.byId(contextScopeId, contextProcessId).createComment(ansibleCommand) + +ansibleCommand \ No newline at end of file diff --git a/smardigo/provisioning/user-management/user-management.json b/smardigo/provisioning/user-management/user-management.json new file mode 100644 index 0000000..9b84976 --- /dev/null +++ b/smardigo/provisioning/user-management/user-management.json @@ -0,0 +1,15 @@ +{ + "groups" : [ { + "id" : "user", + "name" : "User" + }, { + "id" : "head", + "name" : "Head" + }, { + "id" : "maintainer", + "name" : "Maintainer" + }, { + "id" : "administrator", + "name" : "Administrator" + } ] +} \ No newline at end of file diff --git a/templates/_docker/docker-compose.yml.j2 b/templates/_docker/docker-compose.yml.j2 index d29799c..b576b04 100644 --- a/templates/_docker/docker-compose.yml.j2 +++ b/templates/_docker/docker-compose.yml.j2 @@ -31,7 +31,6 @@ services: {{ service.name }}: image: "{{ service.image_name }}:{{ service.image_version }}" container_name: "{{ service.name }}" - hostname: "{{ service.name }}" restart: {{ service.restart | default('always') }} {% if service.user is defined diff --git a/templates/smardigo-management-message.json.j2 b/templates/smardigo-management-message.json.j2 new file mode 100644 index 0000000..7ee0d0f --- /dev/null +++ b/templates/smardigo-management-message.json.j2 @@ -0,0 +1,5 @@ +{ + "message": "action-executed-{{ smardigo_management_action }}", + "localVariables": {}, + "processVariables": {} +} \ No newline at end of file