diff --git a/.github/workflows/enteprise.yml b/.github/workflows/enteprise.yml index 0c0aad42d..ee12d153f 100644 --- a/.github/workflows/enteprise.yml +++ b/.github/workflows/enteprise.yml @@ -149,6 +149,9 @@ jobs: - name: multimachine vars: vars.yml desc: EC2 ACS 7.3 clustered (RHEL8) + - name: opensearch + vars: vars.yml + desc: EC2 ACS 7.3 opensearch (RHEL8) env: AWS_REGION: eu-west-1 MOLECULE_IT_AWS_VPC_SUBNET_ID: subnet-6bdd4223 diff --git a/molecule/multimachine/prepare.yml b/molecule/multimachine/prepare.yml index 1c2b7ee94..9dd50a175 100644 --- a/molecule/multimachine/prepare.yml +++ b/molecule/multimachine/prepare.yml @@ -105,7 +105,7 @@ --engine-type ACTIVEMQ \ --host-instance-type mq.t3.micro \ --engine-version 5.15.15 \ - --users Password={{ activemq_password }},Username=alfresco \ + --users Password={{ activemq_password | quote }},Username=alfresco \ --security-groups {{ ec2_groups_lookup.security_groups[0].group_id }} \ --publicly-accessible \ --no-auto-minor-version-upgrade diff --git a/molecule/opensearch/cleanup.yml b/molecule/opensearch/cleanup.yml new file mode 100644 index 000000000..92aa19833 --- /dev/null +++ b/molecule/opensearch/cleanup.yml @@ -0,0 +1,25 @@ +--- +- name: Opensearch cleanup + hosts: localhost + gather_facts: false + vars: + aws_region: "{{ lookup('env', 'AWS_REGION') }}" + it_platform: >- + {{ lookup('ansible.builtin.env', 'MOLECULE_IT_PLATFORM') }} + repo_branch: >- + {{ lookup('ansible.builtin.env', 'BRANCH_NAME') }} + build: >- + {{ lookup('ansible.builtin.env', 'BUILD_NUMBER') }} + aws_base_resource_name: "{{ ['molecule', it_platform, repo_branch, build] | join('_') }}" + domain_name: >- + {{ aws_base_resource_name | ansible.builtin.regex_replace('[^a-zA-Z0-9]','-') | lower | truncate(28, True, '') }} + tasks: + - name: Destroy Opensearch domain {{ domain_name }} + community.aws.opensearch: + domain_name: "{{ domain_name }}" + state: absent + wait_timeout: 1200 + wait: true + +- name: Default cleanup + import_playbook: ../default/cleanup.yml diff --git a/molecule/opensearch/host_vars/search3.yml b/molecule/opensearch/host_vars/search3.yml new file mode 100644 index 000000000..cee7d5822 --- /dev/null +++ b/molecule/opensearch/host_vars/search3.yml @@ -0,0 +1,2 @@ +--- +# required for settings vars in prepare step diff --git a/molecule/opensearch/hosts.yml b/molecule/opensearch/hosts.yml new file mode 100644 index 000000000..fdffa2a0f --- /dev/null +++ b/molecule/opensearch/hosts.yml @@ -0,0 +1 @@ +# placeholder diff --git a/molecule/opensearch/molecule.yml b/molecule/opensearch/molecule.yml new file mode 100644 index 000000000..b6e7dbc11 --- /dev/null +++ b/molecule/opensearch/molecule.yml @@ -0,0 +1,44 @@ +--- +dependency: + name: galaxy +driver: + name: ec2 +verifier: + name: ansible +platforms: + - name: search3 + image: ${MOLECULE_IT_IMAGE_ID} + instance_type: t3.large + vpc_subnet_id: ${MOLECULE_IT_AWS_VPC_SUBNET_ID} + region: ${AWS_REGION} + tags: + Name: molecule_${MOLECULE_IT_PLATFORM}_${BRANCH_NAME}_${BUILD_NUMBER} + Owner: Ops Readiness Team + Department: Engineering + Production: false + groups: + - database + - activemq + - transformers + - repository + - search_enterprise + - trusted_resource_consumers + - nginx +provisioner: + name: ansible + config_options: + defaults: + pipelining: true + ansible_args: + - -e + - "@tests/test-ssl.yml" + inventory: + links: + group_vars: ../../group_vars + host_vars: ./host_vars + hosts: ./hosts.yml + playbooks: + create: ../default/create.yml + converge: ../../playbooks/acs.yml + destroy: ../default/destroy.yml + verify: ../default/verify.yml diff --git a/molecule/opensearch/prepare.yml b/molecule/opensearch/prepare.yml new file mode 100644 index 000000000..a44b89e3c --- /dev/null +++ b/molecule/opensearch/prepare.yml @@ -0,0 +1,113 @@ +--- +- name: Prepare + hosts: all:!external + gather_facts: false + tasks: + - name: Make sure python3 is installed + package: + name: python3 + state: present + become: true + +- name: Import default prepare playbook + import_playbook: ../default/prepare.yml + +- name: Create Opensearch Domain + hosts: localhost + gather_facts: false + connection: local + vars: + aws_region: "{{ lookup('env', 'AWS_REGION') }}" + it_platform: >- + {{ lookup('ansible.builtin.env', 'MOLECULE_IT_PLATFORM') }} + repo_branch: >- + {{ lookup('ansible.builtin.env', 'BRANCH_NAME') }} + build: >- + {{ lookup('ansible.builtin.env', 'BUILD_NUMBER') }} + aws_base_resource_name: "{{ ['molecule', it_platform, repo_branch, build] | join('_') }}" + domain_name: >- + {{ aws_base_resource_name | ansible.builtin.regex_replace('[^a-zA-Z0-9]','-') | lower | truncate(28, True, '') }} + domain_admin: admin + tasks: + - name: Gather caller info + amazon.aws.aws_caller_info: + register: caller_info + + - name: Gather EC2 metadata + amazon.aws.ec2_instance_info: + filters: + instance-state-name: running + "tag:Name": "{{ aws_base_resource_name }}" + register: meta_ec2 + + - name: Early secrets loading from vault + include_vars: ../../vars/secrets.yml + + - name: Request OpenSearch domain creation + vars: + ec2_sg: "{{ meta_ec2.instances | json_query('[].security_groups[].group_id') }}" + ec2_instance_ids: "{{ meta_ec2.instances | map(attribute='instance_id') }}" + ec2_subnet_ids: "{{ meta_ec2.instances | map(attribute='subnet_id') }}" + community.aws.opensearch: + domain_name: "{{ domain_name }}" + engine_version: OpenSearch_1.3 + wait: true + wait_timeout: 1200 + cluster_config: + instance_type: c6g.large.search + instance_count: 2 + zone_awareness: false + dedicated_master: false + ebs_options: + ebs_enabled: true + volume_type: gp2 + volume_size: 10 + access_policies: + Version: 2012-10-17 + Statement: + - Effect: Allow + Principal: + AWS: "*" + Action: + - es:* + Resource: >- + arn:aws:es:{{ aws_region }}:{{ caller_info.account }}:domain/{{ domain_name }}/* + encryption_at_rest_options: + enabled: true + node_to_node_encryption_options: + enabled: true + domain_endpoint_options: + enforce_https: true + advanced_security_options: + enabled: true + internal_user_database_enabled: true + master_user_options: + master_user_name: "{{ domain_admin }}" + master_user_password: "{{ elasticsearch_password }}" + vpc_options: + security_groups: "{{ ec2_sg | unique }}" + subnets: "{{ ec2_subnet_ids | unique }}" + tags: + ClientInstances: "{{ molecule_yml.platforms | map(attribute='name') | join('/') }}" + Owner: Ops Readiness Team + Department: Engineering + Production: false + + - name: Gather OpenSearch domain info + community.aws.opensearch_info: + domain_name: "{{ domain_name }}" + until: es_domain.domains[0].domain_status.endpoints.vpc | default(false) + delay: 30 + retries: 10 + register: es_domain + + - name: Hack inventory to add Opensearch domain + vars: + eshost: "{{ es_domain.domains[0].domain_status.endpoints.vpc }}" + esattrs: + elasticsearch_username: "{{ domain_admin }}" + elasticsearch_port: 443 + elasticsearch_protocol: https + ansible.builtin.template: + src: hosts.yml.j2 + dest: hosts.yml diff --git a/molecule/opensearch/templates/hosts.yml.j2 b/molecule/opensearch/templates/hosts.yml.j2 new file mode 100644 index 000000000..056cc6f5d --- /dev/null +++ b/molecule/opensearch/templates/hosts.yml.j2 @@ -0,0 +1,8 @@ +all: + children: + external: + children: + external_elasticsearch: + hosts: + {{ eshost }}: + {{ esattrs | to_yaml }} diff --git a/molecule/opensearch/vars.yml b/molecule/opensearch/vars.yml new file mode 100644 index 000000000..14aa5023a --- /dev/null +++ b/molecule/opensearch/vars.yml @@ -0,0 +1,3 @@ +MOLECULE_IT_IMAGE_ID: ami-0f0f1c02e5e4d9d9f # rhel8 +MOLECULE_IT_TEST_CONFIG: tests/test-config-latest-nosync.json +MOLECULE_IT_PLATFORM: opensearch diff --git a/roles/activemq/molecule/default/tests/test_activemq.py b/roles/activemq/molecule/default/tests/test_activemq.py index 8f2207383..d07af32a1 100644 --- a/roles/activemq/molecule/default/tests/test_activemq.py +++ b/roles/activemq/molecule/default/tests/test_activemq.py @@ -50,7 +50,7 @@ def test_activemq_service(host): def test_activemq_web_console(host, get_ansible_vars): "Check that ActiveMQ web console is available and returns a HTTP 200 for the home page" - cmd = host.run("curl -iL --user admin:{} http://{}:8161".format(get_ansible_vars["activemq_password"], test_host)) + cmd = host.run('curl -iL --user admin:"{}" http://{}:8161'.format(get_ansible_vars["activemq_password"], test_host)) assert_that(cmd.stdout, contains_string("Welcome to the Apache ActiveMQ!")) assert_that(cmd.stdout, contains_string("200 OK")) diff --git a/roles/activemq/tasks/main.yml b/roles/activemq/tasks/main.yml index a61340f75..0b91a439b 100644 --- a/roles/activemq/tasks/main.yml +++ b/roles/activemq/tasks/main.yml @@ -83,7 +83,7 @@ s: http://www.springframework.org/schema/beans a: http://activemq.apache.org/schema/core - - name: configure ActiveMQ users + - name: Configure ActiveMQ users ansible.builtin.lineinfile: path: "{{ activemq_conf }}/{{ item.file }}.properties" line: "{{ item.line }}" @@ -95,8 +95,8 @@ - file: groups line: admins={{ activemq_username }} - file: jetty-realm - line: "{{ activemq_username }}: {{ activemq_password }}, admin" - no_log: True + line: "{{ activemq_username }}: MD5:{{ activemq_password | md5 }}, admin" + no_log: true - name: Change location of ActiveMQ logs replace: diff --git a/roles/repository/templates/alfresco-global.properties.j2 b/roles/repository/templates/alfresco-global.properties.j2 index 6afa1f92a..efdb5dd00 100644 --- a/roles/repository/templates/alfresco-global.properties.j2 +++ b/roles/repository/templates/alfresco-global.properties.j2 @@ -37,6 +37,8 @@ elasticsearch.indexName=alfresco elasticsearch.host={{ elasticsearch_host }} elasticsearch.port={{ ports_cfg.elasticsearch.http }} elasticsearch.secureComms={% if elasticsearch_protocol == 'https' %}https{% else %}none{% endif +%} +elasticsearch.user={{ elasticsearch_username | default('') }} +elasticsearch.password={{ elasticsearch_password | default('') }} {% else %} index.subsystem.name=noindex {% endif %} @@ -54,7 +56,7 @@ encryption.cipherAlgorithm=DESede/CBC/PKCS5Padding encryption.keystore.type=JCEKS encryption.keystore.backup.type=JCEKS {% endif %} - +encryption.ssl.truststore.location={{ java_home }}/lib/security/cacerts dir.license.external={{ settings_folder }}/licenses alfresco.cluster.enabled={% if groups['repository'] | length > 1 and not cluster_keepoff %}true{% else %}false{% endif %} diff --git a/scripts/generate-secret.sh b/scripts/generate-secret.sh index 851ddb2d9..c6ba84aab 100755 --- a/scripts/generate-secret.sh +++ b/scripts/generate-secret.sh @@ -21,7 +21,14 @@ if [ -z "${SECRET_KEY}" ]; then exit_abnormal fi -RANDOM_STRING=$(openssl rand -base64 33) +RANDOM_STRING=$(\ + ANSIBLE_FORCE_COLOR=False \ + ANSIBLE_NOCOLOR=True \ + ansible -m ansible.builtin.command \ + -a "echo {{ lookup('password','/dev/null',chars=['ascii_letters','digits','+.$?/#@^}()[]_'],length=33) }}" \ + localhost -o 2>/dev/null \ + | awk '{print $NF}' \ +) if [ "$MODE" == 'plaintext' ]; then echo "${SECRET_KEY}: \"$RANDOM_STRING\"" elif [ "$MODE" == 'plugin' ]; then diff --git a/tests/test-config-latest-nosync.json b/tests/test-config-latest-nosync.json new file mode 100644 index 000000000..a7d1fb9ba --- /dev/null +++ b/tests/test-config-latest-nosync.json @@ -0,0 +1,26 @@ +{ + "config": { + "host": "TEST_URL", + "username": "admin", + "password": "admin" + }, + "assertions": { + "acs": { + "edition": "Enterprise", + "version": "7.3.0", + "identity": false, + "modules": [ + { + "id": "org.alfresco.integrations.google.docs", + "version": "3.3.0", + "installed": true + }, + { + "id": "alfresco-aos-module", + "version": "1.5.0", + "installed": true + } + ] + } + } + }