diff --git a/extraconfig/services/openshift-master.yaml b/extraconfig/services/openshift-master.yaml index 1a54e31740..f89f06bc32 100644 --- a/extraconfig/services/openshift-master.yaml +++ b/extraconfig/services/openshift-master.yaml @@ -39,10 +39,6 @@ parameters: description: Mapping of service endpoint -> protocol. Typically set via parameter_defaults in the resource registry. type: json - OpenShiftGlobalVariables: - default: {} - description: Global Ansible variables for OpenShift-Ansible installer. - type: json OpenShiftAnsiblePlaybook: default: '/usr/share/ansible/openshift-ansible/playbooks/deploy_cluster.yml' description: Path to OpenShift-Ansible playbook. @@ -51,18 +47,23 @@ parameters: default: '/usr/share/ansible/openshift-ansible/playbooks/openshift-master/scaleup.yml' description: Path to OpenShift-Ansible playbook. type: string + OpenShiftWorkerScaleupPlaybook: + default: '/usr/share/ansible/openshift-ansible/playbooks/openshift-node/scaleup.yml' + description: Path to OpenShift-Ansible playbook. + type: string OpenShiftUpgradePlaybook: default: '/usr/share/ansible/openshift-ansible/playbooks/byo/openshift-cluster/upgrades/v3_9/upgrade.yml' description: Path to OpenShift-Ansible Upgrade playbook. type: string + OpenShiftGlobalVariables: + default: {} + description: Global Ansible variables for OpenShift-Ansible installer. + type: json + # TODO(mandre) Add as a inventory group var OpenShiftMasterNodeVars: default: {} description: OpenShift node vars specific for the master nodes type: json - OpenShiftWorkerNodeVars: - default: {} - description: OpenShift node vars specific for the worker nodes - type: json DockerInsecureRegistryAddress: description: Optional. The IP Address and Port of an insecure docker namespace that will be configured in /etc/sysconfig/docker. @@ -82,362 +83,353 @@ parameters: description: etcd container image for openshift type: string +resources: + + OpenShiftNode: + type: ./openshift-node.yaml + properties: + EndpointMap: {get_param: EndpointMap} + ServiceNetMap: {get_param: ServiceNetMap} + DefaultPasswords: {get_param: DefaultPasswords} + RoleName: {get_param: RoleName} + RoleParameters: {get_param: RoleParameters} + outputs: role_data: description: Role data for the Openshift Service value: service_name: openshift_master config_settings: - tripleo.openshift_master.firewall_rules: - '200 openshift-master api': - dport: 6443 - proto: tcp - '200 openshift-master etcd': - dport: - - 2379 - - 2380 - proto: tcp + map_merge: + - get_attr: [OpenShiftNode, role_data, config_settings] + - tripleo.openshift_master.firewall_rules: + '200 openshift-master api': + dport: 6443 + proto: tcp + '200 openshift-master etcd': + dport: + - 2379 + - 2380 + proto: tcp upgrade_tasks: [] step_config: '' external_deploy_tasks: - - name: openshift_master step 2 - when: step == '2' - tags: openshift - block: - - name: create openshift temp dirs - file: - path: "{{item}}" - state: directory - with_items: - - "{{playbook_dir}}/openshift/inventory" + list_concat: + - get_attr: [OpenShiftNode, role_data, external_deploy_tasks] + - - name: openshift_master step 2 + when: step == '2' + tags: openshift + block: + - name: set openshift global vars fact + set_fact: + openshift_global_vars: + map_merge: + - openshift_release: '3.10' + openshift_version: '3.10' + openshift_image_tag: + yaql: + expression: + $.data.image.rightSplit(":", 1)[1] + data: + image: {get_param: DockerOpenShiftBaseImage} + openshift_enable_excluders: false + openshift_deployment_type: origin + openshift_use_external_openvswitch: true + openshift_docker_selinux_enabled: false + # Disable services we're not using for now + openshift_enable_service_catalog: false + template_service_broker_install: false + # Needed for containerized deployment + skip_version: true + # Fatal and Errors only + debug_level: 0 + openshift_master_cluster_method: native + openshift_master_cluster_hostname: {get_param: [EndpointMap, OpenshiftPublic, host]} + openshift_master_cluster_public_hostname: {get_param: [EndpointMap, OpenshiftPublic, host]} + # Local Registry + openshift_examples_modify_imagestreams: true + oreg_url: + yaql: + expression: + $.data.image.rightSplit(":", 1).join("-${component}:") + data: + image: {get_param: DockerOpenShiftBaseImage} + etcd_image: {get_param: DockerOpenShiftEtcdImage} + osm_etcd_image: {get_param: DockerOpenShiftEtcdImage} + osm_image: {get_param: DockerOpenShiftBaseImage} + osn_image: {get_param: DockerOpenShiftNodeImage} + openshift_cockpit_deployer_image: {get_param: DockerOpenShiftCockpitImage} + openshift_docker_additional_registries: {get_param: DockerInsecureRegistryAddress} + openshift_master_bootstrap_auto_approve: true + osm_controller_args: {"experimental-cluster-signing-duration": ["20m"]} + - {get_param: OpenShiftGlobalVariables} + tripleo_stack_action: {get_param: StackAction} + openshift_master_node_vars: {get_param: OpenShiftMasterNodeVars} - - name: set openshift global vars fact - set_fact: - openshift_global_vars: - map_merge: - - openshift_release: '3.10' - openshift_version: '3.10' - openshift_image_tag: - yaql: - expression: - $.data.image.rightSplit(":", 1)[1] - data: - image: {get_param: DockerOpenShiftBaseImage} - openshift_enable_excluders: false - openshift_deployment_type: origin - openshift_use_external_openvswitch: true - openshift_docker_selinux_enabled: false - # Disable services we're not using for now - openshift_enable_service_catalog: false - template_service_broker_install: false - # Needed for containerized deployment - skip_version: true - # Fatal and Errors only - debug_level: 0 - openshift_master_cluster_method: native - openshift_master_cluster_hostname: {get_param: [EndpointMap, OpenshiftPublic, host]} - openshift_master_cluster_public_hostname: {get_param: [EndpointMap, OpenshiftPublic, host]} - # Local Registry - openshift_examples_modify_imagestreams: true - oreg_url: - yaql: - expression: - $.data.image.rightSplit(":", 1).join("-${component}:") - data: - image: {get_param: DockerOpenShiftBaseImage} - etcd_image: {get_param: DockerOpenShiftEtcdImage} - osm_etcd_image: {get_param: DockerOpenShiftEtcdImage} - osm_image: {get_param: DockerOpenShiftBaseImage} - osn_image: {get_param: DockerOpenShiftNodeImage} - openshift_cockpit_deployer_image: {get_param: DockerOpenShiftCockpitImage} - openshift_web_console_prefix: - yaql: - expression: - $.data.image.rightSplit(":", 1)[0] + "-" - data: - image: {get_param: DockerOpenShiftBaseImage} - openshift_docker_additional_registries: {get_param: DockerInsecureRegistryAddress} - openshift_master_bootstrap_auto_approve: true - osm_controller_args: {"experimental-cluster-signing-duration": ["20m"]} - - {get_param: OpenShiftGlobalVariables} - tripleo_role_name: {get_param: RoleName} - tripleo_stack_action: {get_param: StackAction} - openshift_master_node_vars: {get_param: OpenShiftMasterNodeVars} - openshift_worker_node_vars: {get_param: OpenShiftWorkerNodeVars} - openshift_master_network: {get_param: [ServiceNetMap, OpenshiftMasterNetwork]} + - name: set role facts for generating inventory + set_fact: + tripleo_role_name: {get_param: RoleName} - # NOTE(flaper87): Check if origin-node is running - # in the openshift nodes so we can flag the node - # as new later on. - # This task ignores errors because docker inspect - # exits with 1 if origin-node doesn't exist. Perhaps - # we could use failed_when instead of ignoring the - # errors. Future improvement. - - name: Check if origin-node is running - become: true - shell: > - docker inspect atomic-enterprise-master-api > /dev/null 2>&1 - || docker inspect origin-master-api > /dev/null 2>&1 - || echo "false" - register: origin_nodes - delegate_to: "{{item}}" - with_items: "{{ groups[tripleo_role_name] | default([]) }}" + # FIXME(mandre) This task always fails: + # - become:true doesn't work in that context (containerized undercloud issue?) + # - there is no origin-master-api docker container + # We should be checking for systemd service status instead. + # NOTE(flaper87): Check if origin-node is running in the openshift + # nodes so we can flag the node as new later on. + # + # This task ignores errors because docker inspect exits with 1 if + # origin-node doesn't exist. Perhaps we could use failed_when + # instead of ignoring the errors. Future improvement. + - name: Check if origin-node is running + become: true + shell: > + docker inspect atomic-enterprise-master-api > /dev/null 2>&1 + || docker inspect origin-master-api > /dev/null 2>&1 + || echo "false" + register: origin_nodes + delegate_to: "{{item}}" + with_items: "{{ groups[tripleo_role_name] | default([]) }}" - # NOTE(flaper87): Create all the nodes objects - # now, as yaml dicts, instead of formatting - # everything as part of a template. - # We consider new_node all the nodes that - # exited with 1 in the previous task. - # - # Future Improvement: Use hostvars[] syntax - # instead of raw_get to reduce verbosity. - - set_fact: - nodes: - - new_node: "{{origin_nodes.results | selectattr('item', 'equalto', item) | selectattr('stdout', 'equalto', 'false') | list | count > 0}}" - hostname: "{{item}}" - ansible_user: "{{ hostvars[item]['ansible_user'] | default(hostvars[item]['ansible_ssh_user']) | default('root') }}" - ansible_host: "{{ hostvars[item]['ansible_host'] | default(item) }}" - ansible_become: true - containerized: true - openshift_node_group_name: 'node-config-master-infra' - etcd_ip: "{{hostvars[item][openshift_master_network + '_ip']}}" - openshift_ip: "{{hostvars[item][openshift_master_network + '_ip']}}" - openshift_master_bind_addr: "{{hostvars[item][openshift_master_network + '_ip']}}" - openshift_public_ip: "{{hostvars[item][openshift_master_network + '_ip']}}" - openshift_hostname: "{{hostvars[item][openshift_master_network + '_ip']}}" - openshift_public_hostname: "{{hostvars[item][openshift_master_network + '_ip']}}" + - set_fact: + nodes: + - new_node: "{{origin_nodes.results | selectattr('item', 'equalto', item) | selectattr('stdout', 'equalto', 'false') | list | count > 0}}" + hostname: "{{item}}" + register: all_master_nodes + with_items: "{{groups[tripleo_role_name] | default([]) }}" - register: all_master_nodes - with_items: "{{groups[tripleo_role_name] | default([]) }}" + - set_fact: + master_nodes: "{{all_master_nodes.results | map(attribute='ansible_facts') | map(attribute='nodes') | flatten | list}}" + new_master_nodes: "{{all_master_nodes.results | map(attribute='ansible_facts') | map(attribute='nodes') | flatten | selectattr('new_node', 'equalto', True) | list}}" - - set_fact: - master_nodes: "{{all_master_nodes.results | map(attribute='ansible_facts') | map(attribute='nodes') | flatten | list}}" - new_masters: "{{all_master_nodes.results | map(attribute='ansible_facts') | map(attribute='nodes') | flatten | selectattr('new_node', 'equalto', True) | list}}" + # NOTE(flaper87): Every master node will be in the masters group + # but only new master nodes will be in the new_masters section, which + # will be created only if there are nodes to add. We'll add `new_masters` + # to the OSEv3 group regardless to simplify the implementation. Ansible + # will ignore the section if it doesn't exist or if it's empty + - name: generate openshift inventory for openshift_master service + copy: + dest: "{{playbook_dir}}/openshift/inventory/{{tripleo_role_name}}_openshift_master.yml" + content: | + {% if master_nodes | count > 0%} + all: + children: + masters: + hosts: + {% for host in master_nodes -%} + {{host.hostname}}: + {% endfor %} - # NOTE(flaper87): Every master node will be in the masters group - # but only new master nodes will be in the new_masters section, which - # will be created only if there are nodes to add. We'll add `new_masters` - # to the OSEv3 group regardless to simplify the implementation. Ansible - # will ignore the section if it doesn't exist or if it's empty - - name: generate openshift inventory for openshift_master service - copy: - dest: "{{playbook_dir}}/openshift/inventory/{{tripleo_role_name}}_openshift_master.yml" - content: | - {% if master_nodes | count > 0%} - masters: - hosts: - {% for host in master_nodes %} - {{host.hostname}}: - {{host | combine(openshift_master_node_vars) | to_nice_yaml() | indent(6)}} - {% endfor %} + vars: + {{openshift_master_node_vars | to_nice_yaml() | indent(6)}} - nodes: - hosts: - {% for host in master_nodes %} - {{host.hostname}}: - {{host | combine(openshift_master_node_vars) | to_nice_yaml() | indent(6)}} - {% endfor %} - {% endif %} + {% if new_master_nodes | count > 0 -%} + new_masters: + hosts: + # FIXME(mandre) + # patterns do not work in inventory files, so we + # can't write something like + # hosts: + # new_nodes:&masters: {} + # + # Also impossible to register var with templated + # name, we can't re-use the all_role_nodes var + # for the master role in openshift-node.yaml + {% for host in new_master_nodes -%} + {{host.hostname}}: + {% endfor %} + {% endif %} + {% endif %} - {% if new_masters | count > 0 %} - new_masters: - hosts: - {% for host in new_masters %} - {{host.hostname}}: - {{host | combine(openshift_master_node_vars) | to_nice_yaml() | indent(6)}} - {% endfor %} + - name: generate openshift inventory for groups + copy: + dest: "{{playbook_dir}}/openshift/inventory/groups.yml" + content: | + all: + children: + etcd: + children: + masters: {} - new_nodes: - hosts: - {% for host in master_nodes %} - {{host.hostname}}: - {{host | combine(openshift_master_node_vars) | to_nice_yaml() | indent(6)}} - {% endfor %} + new_etcd: + children: + new_masters: {} - new_etcd: - children: - new_masters: {} - {% endif %} + OSEv3: + children: + masters: {} + nodes: {} + new_masters: {} + new_nodes: {} + {% if groups['openshift_glusterfs'] | default([]) %}glusterfs: {}{% endif %} - etcd: - children: - masters: {} + - name: generate openshift global defaults + copy: + dest: "{{playbook_dir}}/openshift/global_defaults.yml" + content: | + containerized: true + openshift_master_cluster_method: native + openshift_use_dnsmasq: true + openshift_use_external_openvswitch: true - OSEv3: - children: - masters: {} - nodes: {} - new_masters: {} - new_nodes: {} - {% if groups['openshift_glusterfs'] | default([]) %}glusterfs: {}{% endif %} + - name: generate openshift global vars + copy: + dest: "{{playbook_dir}}/openshift/global_vars.yml" + content: "{{openshift_global_vars|to_nice_yaml}}" - - name: generate openshift global defaults - copy: - dest: "{{playbook_dir}}/openshift/global_defaults.yml" - content: | - containerized: true - openshift_master_cluster_method: native - openshift_use_dnsmasq: true - openshift_use_external_openvswitch: true + - name: set openshift ansible playbook paths + set_fact: + openshift_ansible_playbook_path: {get_param: OpenShiftAnsiblePlaybook} + openshift_master_scaleup_playbook_path: {get_param: OpenShiftMasterScaleupPlaybook} + openshift_worker_scaleup_playbook_path: {get_param: OpenShiftWorkerScaleupPlaybook} + openshift_upgrade_playbook_path: {get_param: OpenShiftUpgradePlaybook} - - name: generate openshift global vars - copy: - dest: "{{playbook_dir}}/openshift/global_vars.yml" - content: "{{openshift_global_vars|to_nice_yaml}}" + # NOTE(flaper87): We'll use openshift_ansible_scaleup_playbook_path + # if there are new master or new worker nodes and we are doing an + # UPDATE. For all the other cases, we shall use the deploy playbook. + - name: generate openshift playbook + copy: + dest: "{{playbook_dir}}/openshift/playbook.yml" + content: | + # NOTE(flaper87): The NetworkManager setup has been moved + # into openshift-ansible but it's not been released yet. + # This code will go away as soon as an rpm with the required + # roles hits the repo. + - name: OpenShift networking preparation + hosts: all - - name: set openshift ansible playbook paths - set_fact: - openshift_ansible_playbook_path: {get_param: OpenShiftAnsiblePlaybook} - openshift_master_scaleup_playbook_path: {get_param: OpenShiftMasterScaleupPlaybook} - openshift_upgrade_playbook_path: {get_param: OpenShiftUpgradePlaybook} + tasks: + - name: install NetworkManager + package: + name: NetworkManager + state: present - # NOTE(flaper87): We'll use openshift_ansible_scaleup_playbook_path - # if there are new master or new worker nodes and we are doing an - # UPDATE. For all the other cases, we shall use the deploy playbook. - - name: generate openshift playbook - copy: - dest: "{{playbook_dir}}/openshift/playbook.yml" - content: | - # NOTE(flaper87): The NetworkManager setup has been moved - # into openshift-ansible but it's not been released yet. - # This code will go away as soon as an rpm with the required - # roles hits the repo. - - name: OpenShift networking preparation - hosts: all + - name: generate nm dispatcher script + copy: + dest: "/etc/NetworkManager/dispatcher.d/99-os-net-config-origin-dns.sh" + owner: root + mode: 0755 + content: >- + #!/bin/bash -x - tasks: - - name: install NetworkManager - package: - name: NetworkManager - state: present + DEVS=$(nmcli device | grep unmanaged | awk '{print $1}') - - name: generate nm dispatcher script - copy: - dest: "/etc/NetworkManager/dispatcher.d/99-os-net-config-origin-dns.sh" - owner: root - mode: 0755 - content: >- - #!/bin/bash -x + for dev in $DEVS; + do + temp="${dev%\"}" + temp="${temp#\"}" + export DEVICE_IFACE=$temp - DEVS=$(nmcli device | grep unmanaged | awk '{print $1}') + /etc/NetworkManager/dispatcher.d/99-origin-dns.sh $DEVICE_IFACE up + done - for dev in $DEVS; - do - temp="${dev%\"}" - temp="${temp#\"}" - export DEVICE_IFACE=$temp - - /etc/NetworkManager/dispatcher.d/99-origin-dns.sh $DEVICE_IFACE up - done - - - name: Enable NetworkManager - service: - name: NetworkManager - state: restarted - enabled: yes + - name: Enable NetworkManager + service: + name: NetworkManager + state: restarted + enabled: yes - - include: "/usr/share/ansible/openshift-ansible/playbooks/prerequisites.yml" - {% if tripleo_stack_action == 'UPDATE' and new_masters | count > 0 %} - - include: "{{openshift_master_scaleup_playbook_path}}" - {% endif %} + - include: "/usr/share/ansible/openshift-ansible/playbooks/prerequisites.yml" + {% if tripleo_stack_action == 'UPDATE' and new_masters | count > 0 %} + - include: "{{openshift_master_scaleup_playbook_path}}" + {% endif %} - {% if tripleo_stack_action == 'UPDATE' and new_nodes | count > 0 %} - - include: "{{openshift_worker_scaleup_playbook_path}}" - {% endif %} + {% if tripleo_stack_action == 'UPDATE' and new_nodes | count > 0 %} + - include: "{{openshift_worker_scaleup_playbook_path}}" + {% endif %} - {% if tripleo_stack_action == 'UPDATE' and openshift_upgrade %} - - include: "{{openshift_upgrade_playbook_path}}" - {% endif %} + {% if tripleo_stack_action == 'UPDATE' and openshift_upgrade %} + - include: "{{openshift_upgrade_playbook_path}}" + {% endif %} - {% if tripleo_stack_action == 'CREATE' or (tripleo_stack_action == 'UPDATE' and (new_masters + new_nodes) | count == 0) %} - - include: "{{openshift_ansible_playbook_path}}" - {% endif %} + {% if tripleo_stack_action == 'CREATE' or (tripleo_stack_action == 'UPDATE' and (new_masters + new_nodes) | count == 0) %} + - include: "{{openshift_ansible_playbook_path}}" + {% endif %} - - name: Simple validation OpenShift is actually deployed - hosts: masters + - name: Simple validation OpenShift is actually deployed + hosts: masters - tasks: - - name: Check oc status - command: oc status --suggest - register: oc_status - become: true + tasks: + - name: Check oc status + command: oc status --suggest + register: oc_status + become: true - - name: Register failure if oc status fails - command: echo true - register: oc_status_failed - when: '"fail" in oc_status.stdout' + - name: Register failure if oc status fails + command: echo true + register: oc_status_failed + when: '"fail" in oc_status.stdout' - - debug: - var: oc_status.stdout_lines + - debug: + var: oc_status.stdout_lines - - name: Check oc get dc/router - command: "oc get dc/router -o jsonpath='{.status.readyReplicas}'" - register: oc_get_router - become: true + - name: Check oc get dc/router + command: "oc get dc/router -o jsonpath='{.status.readyReplicas}'" + register: oc_get_router + become: true - - name: Register failure if oc get dc/router fails - command: echo true - register: oc_get_router_failed - when: 'oc_get_router.stdout|int < 1' + - name: Register failure if oc get dc/router fails + command: echo true + register: oc_get_router_failed + when: 'oc_get_router.stdout|int < 1' - - debug: - var: oc_get_router.stdout + - debug: + var: oc_get_router.stdout - - name: Check oc get dc/docker-registry - command: "oc get dc/docker-registry -o jsonpath='{.status.readyReplicas}'" - register: oc_get_registry - become: true + - name: Check oc get dc/docker-registry + command: "oc get dc/docker-registry -o jsonpath='{.status.readyReplicas}'" + register: oc_get_registry + become: true - - name: Register failure if oc get dc/docker-registry fails - command: echo true - register: oc_get_registry_failed - when: 'oc_get_registry.stdout|int < 1' + - name: Register failure if oc get dc/docker-registry fails + command: echo true + register: oc_get_registry_failed + when: 'oc_get_registry.stdout|int < 1' - - debug: - var: oc_get_registry.stdout + - debug: + var: oc_get_registry.stdout - - name: Check oc get nodes - command: oc get nodes --all-namespaces - register: oc_get_nodes - become: true + - name: Check oc get nodes + command: oc get nodes --all-namespaces + register: oc_get_nodes + become: true - - name: Register failure if oc get nodes fails - command: echo true - register: oc_get_nodes_failed - when: '"NotReady" in oc_get_nodes.stdout' + - name: Register failure if oc get nodes fails + command: echo true + register: oc_get_nodes_failed + when: '"NotReady" in oc_get_nodes.stdout' - - debug: - var: oc_get_nodes.stdout_lines + - debug: + var: oc_get_nodes.stdout_lines - - name: Fail the playbook if any validations failed - fail: - when: > - oc_status_failed.changed or - oc_get_nodes_failed.changed or - oc_get_router_failed.changed or - oc_get_registry_failed.changed + - name: Fail the playbook if any validations failed + fail: + when: > + oc_status_failed.changed or + oc_get_nodes_failed.changed or + oc_get_router_failed.changed or + oc_get_registry_failed.changed - - name: set openshift command - set_fact: - openshift_command: >- - {%- if openshift_command is defined -%} - {{openshift_command}} - {%- else -%} - ANSIBLE_HOST_KEY_CHECKING=False - ansible-playbook - -i '{{playbook_dir}}/openshift/inventory' - --extra-vars '@{{playbook_dir}}/openshift/global_defaults.yml' - --extra-vars '@{{playbook_dir}}/openshift/global_vars.yml' - '{{playbook_dir}}/openshift/playbook.yml' - {%- endif -%} - - name: print openshift command - debug: - var: openshift_command - - name: run openshift (immediate log at {{playbook_dir}}/openshift/playbook.log) - shell: | - {{openshift_command}} 2>&1 | tee {{playbook_dir}}/openshift/playbook.log - exit ${PIPESTATUS[0]} + - name: set openshift command + set_fact: + openshift_command: >- + {%- if openshift_command is defined -%} + {{openshift_command}} + {%- else -%} + ANSIBLE_HOST_KEY_CHECKING=False + ansible-playbook + -i '{{playbook_dir}}/openshift/inventory' + --extra-vars '@{{playbook_dir}}/openshift/global_defaults.yml' + --extra-vars '@{{playbook_dir}}/openshift/global_vars.yml' + '{{playbook_dir}}/openshift/playbook.yml' + {%- endif -%} + - name: print openshift command + debug: + var: openshift_command + - name: run openshift (immediate log at {{playbook_dir}}/openshift/playbook.log) + shell: | + {{openshift_command}} 2>&1 | tee {{playbook_dir}}/openshift/playbook.log + exit ${PIPESTATUS[0]} external_upgrade_tasks: - name: set OpenShift upgrade facts diff --git a/extraconfig/services/openshift-node.yaml b/extraconfig/services/openshift-node.yaml new file mode 100644 index 0000000000..e11200a8c9 --- /dev/null +++ b/extraconfig/services/openshift-node.yaml @@ -0,0 +1,163 @@ +heat_template_version: rocky + +description: External tasks definition for OpenShift + +parameters: + StackAction: + type: string + description: > + Heat action on performed top-level stack. Note StackUpdateType is + set to UPGRADE when a major-version upgrade is in progress. + constraints: + - allowed_values: ['CREATE', 'UPDATE'] + RoleNetIpMap: + default: {} + type: json + ServiceData: + default: {} + description: Dictionary packing service data + type: json + ServiceNetMap: + default: {} + description: Mapping of service_name -> network name. Typically set + via parameter_defaults in the resource registry. This + mapping overrides those in ServiceNetMapDefaults. + type: json + DefaultPasswords: + default: {} + type: json + RoleName: + default: '' + description: Role name on which the service is applied + type: string + RoleParameters: + default: {} + description: Parameters specific to the role + type: json + EndpointMap: + default: {} + description: Mapping of service endpoint -> protocol. Typically set + via parameter_defaults in the resource registry. + type: json + OpenShiftNodeGroupName: + default: node-config-all-in-one + description: The group the nodes belong to. + type: string + tags: + - role_specific + +resources: + RoleParametersValue: + type: OS::Heat::Value + properties: + type: json + value: + map_replace: + - map_replace: + - OpenShiftNodeGroupName: OpenShiftNodeGroupName + - values: {get_param: [RoleParameters]} + - values: + OpenShiftNodeGroupName: {get_param: OpenShiftNodeGroupName} + +outputs: + role_data: + description: Role data for the Openshift Service + value: + service_name: openshift_node + config_settings: {} + upgrade_tasks: [] + step_config: '' + external_deploy_tasks: + - name: openshift_node step 1 + when: step == '1' + tags: openshift + block: + - name: create openshift temp dirs + file: + path: "{{item}}" + state: directory + with_items: + - "{{playbook_dir}}/openshift/inventory" + + - name: set role facts for generating inventory + set_fact: + tripleo_role_name: {get_param: RoleName} + tripleo_node_group_name: {get_attr: [RoleParametersValue, value, OpenShiftNodeGroupName]} + openshift_master_network: {get_param: [ServiceNetMap, OpenshiftMasterNetwork]} + + # FIXME(mandre) This task always fails: + # - become:true doesn't work in that context (containerized undercloud issue?) + # - there is no origin-master-api docker container + # We should be checking for systemd service status instead. + # NOTE(flaper87): Check if origin-node is running in the openshift + # nodes so we can flag the node as new later on. + # + # This task ignores errors because docker inspect exits with 1 if + # origin-node doesn't exist. Perhaps we could use failed_when + # instead of ignoring the errors. Future improvement. + - name: Check if origin-node is running + become: true + shell: > + docker inspect atomic-enterprise-master-api > /dev/null 2>&1 + || docker inspect origin-master-api > /dev/null 2>&1 + || echo "false" + register: origin_nodes + delegate_to: "{{item}}" + with_items: "{{ groups[tripleo_role_name] | default([]) }}" + + # NOTE(flaper87): Create all the nodes objects + # now, as yaml dicts, instead of formatting + # everything as part of a template. + # We consider new_node all the nodes that + # exited with 1 in the previous task. + - set_fact: + nodes: + - new_node: "{{origin_nodes.results | selectattr('item', 'equalto', item) | selectattr('stdout', 'equalto', 'false') | list | count > 0}}" + hostname: "{{item}}" + ansible_user: "{{ hostvars[item]['ansible_user'] | default(hostvars[item]['ansible_ssh_user']) | default('root') }}" + ansible_host: "{{ hostvars[item]['ansible_host'] | default(item) }}" + ansible_become: true + containerized: true + openshift_node_group_name: '{{tripleo_node_group_name}}' + etcd_ip: "{{hostvars[item][openshift_master_network + '_ip']}}" + openshift_ip: "{{hostvars[item][openshift_master_network + '_ip']}}" + openshift_master_bind_addr: "{{hostvars[item][openshift_master_network + '_ip']}}" + openshift_public_ip: "{{hostvars[item][openshift_master_network + '_ip']}}" + openshift_hostname: "{{hostvars[item][openshift_master_network + '_ip']}}" + openshift_public_hostname: "{{hostvars[item][openshift_master_network + '_ip']}}" + register: all_role_nodes + with_items: "{{groups[tripleo_role_name] | default([]) }}" + + - set_fact: + role_nodes: "{{all_role_nodes.results | map(attribute='ansible_facts') | map(attribute='nodes') | flatten | list}}" + new_role_nodes: "{{all_role_nodes.results | map(attribute='ansible_facts') | map(attribute='nodes') | flatten | selectattr('new_node', 'equalto', True) | list}}" + + - name: generate openshift inventory for {{tripleo_role_name}} role nodes + copy: + dest: "{{playbook_dir}}/openshift/inventory/{{tripleo_role_name}}_nodes.yml" + content: | + {% if role_nodes | count > 0%} + all: + hosts: + {% for host in role_nodes -%} + {{host.hostname}}: + {{host | to_nice_yaml() | indent(6)}} + {% endfor %} + + children: + nodes: + hosts: + {% for host in role_nodes -%} + {{host.hostname}}: + {% endfor %} + + {% if new_role_nodes | count > 0 -%} + new_nodes: + hosts: + {% for host in new_role_nodes -%} + {{host.hostname}}: + {% endfor %} + + {% endif %} + + {% endif %} diff --git a/extraconfig/services/openshift-worker.yaml b/extraconfig/services/openshift-worker.yaml index 03498be6f9..3ff17501f4 100644 --- a/extraconfig/services/openshift-worker.yaml +++ b/extraconfig/services/openshift-worker.yaml @@ -32,117 +32,40 @@ parameters: description: Mapping of service endpoint -> protocol. Typically set via parameter_defaults in the resource registry. type: json - OpenShiftNodeGroupName: - default: node-config-compute - description: The group the nodes belong to. - type: string - tags: - - role_specific - OpenShiftWorkerScaleupPlaybook: - default: '/usr/share/ansible/openshift-ansible/playbooks/openshift-node/scaleup.yml' - description: Path to OpenShift-Ansible playbook. - type: string + # TODO(mandre) This is unused. Remove it or make it OpenShiftNodeVars + OpenShiftWorkerNodeVars: + default: {} + description: OpenShift node vars specific for the worker nodes + type: json resources: - RoleParametersValue: - type: OS::Heat::Value - properties: - type: json - value: - map_replace: - - map_replace: - - OpenShiftNodeGroupName: OpenShiftNodeGroupName - - values: {get_param: [RoleParameters]} - - values: - OpenShiftNodeGroupName: {get_param: OpenShiftNodeGroupName} + + OpenShiftNode: + type: ./openshift-node.yaml + properties: + EndpointMap: {get_param: EndpointMap} + ServiceNetMap: {get_param: ServiceNetMap} + DefaultPasswords: {get_param: DefaultPasswords} + RoleName: {get_param: RoleName} + RoleParameters: {get_param: RoleParameters} outputs: role_data: description: Role data for the Openshift Service value: - # This service template essentially tags the nodes that we want - # as workers. The actual installation is performed in - # openshift-master service template. service_name: openshift_worker config_settings: - tripleo.openshift_worker.firewall_rules: - '200 openshift-worker kubelet': - dport: - - 10250 - - 10255 - proto: tcp - '200 openshift-worker external services': - dport: '30000-32767' + map_merge: + - get_attr: [OpenShiftNode, role_data, config_settings] + - tripleo.openshift_worker.firewall_rules: + '200 openshift-worker kubelet': + dport: + - 10250 + - 10255 + proto: tcp + '200 openshift-worker external services': + dport: '30000-32767' upgrade_tasks: [] step_config: '' external_deploy_tasks: - - name: openshift_worker step 1 - when: step == '1' - tags: openshift - block: - - name: create openshift temp dirs - file: - path: "{{item}}" - state: directory - with_items: - - "{{playbook_dir}}/openshift/inventory" - - - name: set global vars facts - set_fact: - tripleo_role_name: {get_param: RoleName} - tripleo_node_group_name: {get_attr: [RoleParametersValue, value, OpenShiftNodeGroupName]} - openshift_master_network: {get_param: [ServiceNetMap, OpenshiftMasterNetwork]} - openshift_worker_scaleup_playbook_path: {get_param: OpenShiftWorkerScaleupPlaybook} - - - name: Check if origin-node is running - become: true - shell: > - docker inspect atomic-enterprise-node > /dev/null 2>&1 - || docker inspect origin-node > /dev/null 2>&1 - || echo "false" - register: origin_nodes - delegate_to: "{{item}}" - with_items: "{{ groups[tripleo_role_name] | default([]) }}" - - - set_fact: - nodes: - - new_node: "{{origin_nodes.results | selectattr('item', 'equalto', item) | selectattr('stdout', 'equalto', 'false') | list | count > 0}}" - hostname: "{{item}}" - ansible_user: "{{ hostvars[item]['ansible_user'] | default(hostvars[item]['ansible_ssh_user']) | default('root') }}" - ansible_host: "{{ hostvars[item]['ansible_host'] | default(item) }}" - ansible_become: true - containerized: true - openshift_node_group_name: '{{tripleo_node_group_name }}' - etcd_ip: "{{hostvars[item][openshift_master_network + '_ip']}}" - openshift_ip: "{{hostvars[item][openshift_master_network + '_ip']}}" - openshift_public_ip: "{{hostvars[item][openshift_master_network + '_ip']}}" - openshift_hostname: "{{hostvars[item][openshift_master_network + '_ip']}}" - openshift_public_hostname: "{{hostvars[item][openshift_master_network + '_ip']}}" - openshift_schedulable: '{{tripleo_node_group_name != "node-config-infra"}}' - register: all_worker_nodes - with_items: "{{groups[tripleo_role_name] | default([]) }}" - - - set_fact: - worker_nodes: "{{all_worker_nodes.results | map(attribute='ansible_facts') | map(attribute='nodes') | flatten | list}}" - new_nodes: "{{all_worker_nodes.results | map(attribute='ansible_facts') | map(attribute='nodes') | flatten | selectattr('new_node', 'equalto', True) | list}}" - - - copy: - dest: "{{playbook_dir}}/openshift/inventory/{{tripleo_role_name}}_openshift_worker.yml" - content: | - {% if worker_nodes | count > 0 %} - nodes: - hosts: - {% for host in worker_nodes %} - {{host.hostname}}: - {{host | to_nice_yaml() | indent(6)}} - {% endfor %} - {% endif %} - - {% if new_nodes | count > 0 %} - new_nodes: - hosts: - {% for host in new_nodes %} - {{host.hostname}}: - {{host | to_nice_yaml() | indent(6)}} - {% endfor %} - {% endif %} + - get_attr: [OpenShiftNode, role_data, external_deploy_tasks] diff --git a/roles/OpenShiftAllInOne.yaml b/roles/OpenShiftAllInOne.yaml new file mode 100644 index 0000000000..9374d96772 --- /dev/null +++ b/roles/OpenShiftAllInOne.yaml @@ -0,0 +1,33 @@ +############################################################################### +# Role: OpenShiftAllInOne # +############################################################################### +- name: OpenShiftAllInOne + description: | + OpenShiftAllInOne role + CountDefault: 1 + RoleParametersDefault: + OpenShiftNodeGroupName: 'node-config-all-in-one' + tags: + - primary + - controller + - openshift + networks: + - External + - InternalApi + - Storage + - StorageMgmt + - Tenant + # For systems with both IPv4 and IPv6, you may specify a gateway network for + # each, such as ['ControlPlane', 'External'] + default_route_networks: ['External'] + ServicesDefault: + - OS::TripleO::Services::Docker + - OS::TripleO::Services::Sshd + - OS::TripleO::Services::Ntp + - OS::TripleO::Services::TripleoFirewall + - OS::TripleO::Services::TripleoPackages + - OS::TripleO::Services::HAproxy + - OS::TripleO::Services::Keepalived + - OS::TripleO::Services::OpenShift::Master + - OS::TripleO::Services::OpenShift::Worker + - OS::TripleO::Services::OpenShift::GlusterFS diff --git a/roles/OpenShiftInfra.yaml b/roles/OpenShiftInfra.yaml index d60c1df43a..215a5ce255 100644 --- a/roles/OpenShiftInfra.yaml +++ b/roles/OpenShiftInfra.yaml @@ -5,6 +5,8 @@ description: | OpenShiftInfra role, a specialized worker that only runs infra pods. CountDefault: 1 + RoleParametersDefault: + OpenShiftNodeGroupName: 'node-config-infra' tags: - openshift networks: @@ -12,8 +14,6 @@ - Storage - StorageMgmt - Tenant - RoleParametersDefault: - OpenShiftNodeGroupName: 'node-config-infra' # For systems with both IPv4 and IPv6, you may specify a gateway network for # each, such as ['ControlPlane', 'External'] default_route_networks: ['ControlPlane'] diff --git a/roles/OpenShiftMaster.yaml b/roles/OpenShiftMaster.yaml index f322a0698f..6262cf0e1d 100644 --- a/roles/OpenShiftMaster.yaml +++ b/roles/OpenShiftMaster.yaml @@ -5,6 +5,8 @@ description: | OpenShiftMaster role CountDefault: 1 + RoleParametersDefault: + OpenShiftNodeGroupName: 'node-config-master' tags: - primary - controller diff --git a/roles/OpenShiftWorker.yaml b/roles/OpenShiftWorker.yaml index 7dce0ea5cd..4f3528aa4c 100644 --- a/roles/OpenShiftWorker.yaml +++ b/roles/OpenShiftWorker.yaml @@ -5,6 +5,8 @@ description: | OpenShiftWorker role CountDefault: 1 + RoleParametersDefault: + OpenShiftNodeGroupName: 'node-config-compute' tags: - openshift networks: