diff options
| author | Scott Dodson <sdodson@redhat.com> | 2017-11-16 08:53:17 -0500 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-11-16 08:53:17 -0500 | 
| commit | 8a85bc3a00efb654238a58e1faa2a2629d9360b1 (patch) | |
| tree | 693186d957899c6e3cd38a6ae5aa66392814ff15 /roles/openshift_openstack | |
| parent | 7dcc6292e2ca89fe22675491299cf5853860bed8 (diff) | |
| parent | 2e9d134d4564d87dbbc7853b07204f7f44ee01e6 (diff) | |
| download | openshift-8a85bc3a00efb654238a58e1faa2a2629d9360b1.tar.gz openshift-8a85bc3a00efb654238a58e1faa2a2629d9360b1.tar.bz2 openshift-8a85bc3a00efb654238a58e1faa2a2629d9360b1.tar.xz openshift-8a85bc3a00efb654238a58e1faa2a2629d9360b1.zip | |
Merge pull request #6039 from tomassedovic/openstack-provider-githist
Add the OpenStack provider
Diffstat (limited to 'roles/openshift_openstack')
20 files changed, 1772 insertions, 0 deletions
| diff --git a/roles/openshift_openstack/defaults/main.yml b/roles/openshift_openstack/defaults/main.yml new file mode 100644 index 000000000..5f182e0d6 --- /dev/null +++ b/roles/openshift_openstack/defaults/main.yml @@ -0,0 +1,96 @@ +--- +openshift_openstack_stack_state: 'present' + +openshift_openstack_ssh_ingress_cidr: 0.0.0.0/0 +openshift_openstack_node_ingress_cidr: 0.0.0.0/0 +openshift_openstack_lb_ingress_cidr: 0.0.0.0/0 +openshift_openstack_bastion_ingress_cidr: 0.0.0.0/0 +openshift_openstack_num_etcd: 0 +openshift_openstack_num_masters: 1 +openshift_openstack_num_nodes: 1 +openshift_openstack_num_dns: 0 +openshift_openstack_num_infra: 1 +openshift_openstack_dns_nameservers: [] +openshift_openstack_nodes_to_remove: [] + + +openshift_openstack_cluster_node_labels: +  app: +    region: primary +  infra: +    region: infra + +openshift_openstack_install_debug_packages: false +openshift_openstack_required_packages: +  - docker +  - NetworkManager +  - wget +  - git +  - net-tools +  - bind-utils +  - bridge-utils +openshift_openstack_debug_packages: +  - bash-completion +  - vim-enhanced + +# container-storage-setup +openshift_openstack_container_storage_setup: +  docker_dev: "/dev/sdb" +  docker_vg: "docker-vol" +  docker_data_size: "95%VG" +  docker_dm_basesize: "3G" +  container_root_lv_name: "dockerlv" +  container_root_lv_mount_path: "/var/lib/docker" + + +# populate-dns +openshift_openstack_dns_records_add: [] +openshift_openstack_external_nsupdate_keys: {} + +openshift_openstack_full_dns_domain: "{{ (openshift_openstack_clusterid|trim == '') | ternary(openshift_openstack_public_dns_domain, openshift_openstack_clusterid + '.' + openshift_openstack_public_dns_domain) }}" +openshift_openstack_app_subdomain: "apps" + + +# heat vars +openshift_openstack_clusterid: openshift +openshift_openstack_stack_name: "{{ openshift_openstack_clusterid }}.{{ openshift_openstack_public_dns_domain }}" +openshift_openstack_subnet_prefix: "192.168.99" +openshift_openstack_master_hostname: master +openshift_openstack_infra_hostname: infra-node +openshift_openstack_node_hostname: app-node +openshift_openstack_lb_hostname: lb +openshift_openstack_etcd_hostname: etcd +openshift_openstack_dns_hostname: dns +openshift_openstack_keypair_name: openshift +openshift_openstack_lb_flavor: "{{ openshift_openstack_default_flavor }}" +openshift_openstack_etcd_flavor: "{{ openshift_openstack_default_flavor }}" +openshift_openstack_master_flavor: "{{ openshift_openstack_default_flavor }}" +openshift_openstack_node_flavor: "{{ openshift_openstack_default_flavor }}" +openshift_openstack_infra_flavor: "{{ openshift_openstack_default_flavor }}" +openshift_openstack_dns_flavor: "{{ openshift_openstack_default_flavor }}" +openshift_openstack_master_image: "{{ openshift_openstack_default_image_name }}" +openshift_openstack_infra_image: "{{ openshift_openstack_default_image_name }}" +openshift_openstack_node_image: "{{ openshift_openstack_default_image_name }}" +openshift_openstack_lb_image: "{{ openshift_openstack_default_image_name }}" +openshift_openstack_etcd_image: "{{ openshift_openstack_default_image_name }}" +openshift_openstack_dns_image: "{{ openshift_openstack_default_image_name }}" +openshift_openstack_provider_network_name: null +openshift_openstack_external_network_name: null +openshift_openstack_private_network: >- +  {% if openshift_openstack_provider_network_name | default(None) -%} +  {{ openshift_openstack_provider_network_name }} +  {%- else -%} +  {{ openshift_openstack_private_network_name | default ('openshift-ansible-' + openshift_openstack_stack_name + '-net') }} +  {%- endif -%} +openshift_openstack_master_server_group_policies: [] +openshift_openstack_infra_server_group_policies: [] +openshift_openstack_docker_volume_size: 15 +openshift_openstack_master_volume_size: "{{ openshift_openstack_docker_volume_size }}" +openshift_openstack_infra_volume_size: "{{ openshift_openstack_docker_volume_size }}" +openshift_openstack_node_volume_size: "{{ openshift_openstack_docker_volume_size }}" +openshift_openstack_etcd_volume_size: 2 +openshift_openstack_dns_volume_size: 1 +openshift_openstack_lb_volume_size: 5 +openshift_openstack_use_bastion: false +openshift_openstack_ui_ssh_tunnel: false +openshift_openstack_ephemeral_volumes: false diff --git a/roles/openshift_openstack/tasks/check-prerequisites.yml b/roles/openshift_openstack/tasks/check-prerequisites.yml new file mode 100644 index 000000000..57c7238d1 --- /dev/null +++ b/roles/openshift_openstack/tasks/check-prerequisites.yml @@ -0,0 +1,105 @@ +--- +# Check ansible +- name: Check Ansible version +  assert: +    that: > +      (ansible_version.major == 2 and ansible_version.minor >= 3) or +      (ansible_version.major > 2) +    msg: "Ansible version must be at least 2.3" + +# Check shade +- name: Try to import python module shade +  command: python -c "import shade" +  ignore_errors: yes +  register: shade_result +- name: Check if shade is installed +  assert: +    that: 'shade_result.rc == 0' +    msg: "Python module shade is not installed" + +# Check jmespath +- name: Try to import python module shade +  command: python -c "import jmespath" +  ignore_errors: yes +  register: jmespath_result +- name: Check if jmespath is installed +  assert: +    that: 'jmespath_result.rc == 0' +    msg: "Python module jmespath is not installed" + +# Check python-dns +- name: Try to import python DNS module +  command: python -c "import dns" +  ignore_errors: yes +  register: pythondns_result +- name: Check if python-dns is installed +  assert: +    that: 'pythondns_result.rc == 0' +    msg: "Python module python-dns is not installed" + +# Check jinja2 +- name: Try to import jinja2 module +  command: python -c "import jinja2" +  ignore_errors: yes +  register: jinja_result +- name: Check if jinja2 is installed +  assert: +    that: 'jinja_result.rc == 0' +    msg: "Python module jinja2 is not installed" + +# Check Glance image +- name: Try to get image facts +  os_image_facts: +    image: "{{ openshift_openstack_default_image_name }}" +  register: image_result +- name: Check that image is available +  assert: +    that: "image_result.ansible_facts.openstack_image" +    msg: "Image {{ openshift_openstack_default_image_name }} is not available" + +# Check network name +- name: Try to get network facts +  os_networks_facts: +    name: "{{ openshift_openstack_external_network_name }}" +  register: network_result +  when: not openshift_openstack_provider_network_name|default(None) +- name: Check that network is available +  assert: +    that: "network_result.ansible_facts.openstack_networks" +    msg: "Network {{ openshift_openstack_external_network_name }} is not available" +  when: not openshift_openstack_provider_network_name|default(None) + +# Check keypair +# TODO kpilatov: there is no Ansible module for getting OS keypairs +#                (os_keypair is not suitable for this) +#                this method does not force python-openstackclient dependency +- name: Try to show keypair +  command: > +           python -c 'import shade; cloud = shade.openstack_cloud(); +           exit(cloud.get_keypair("{{ openshift_openstack_keypair_name }}") is None)' +  ignore_errors: yes +  register: key_result +- name: Check that keypair is available +  assert: +    that: 'key_result.rc == 0' +    msg: "Keypair {{ openshift_openstack_keypair_name }} is not available" + +# Check that custom images are available +- include: custom_image_check.yaml +  with_items: +  - "{{ openshift_openstack_master_image }}" +  - "{{ openshift_openstack_infra_image }}" +  - "{{ openshift_openstack_node_image }}" +  - "{{ openshift_openstack_lb_image }}" +  - "{{ openshift_openstack_etcd_image }}" +  - "{{ openshift_openstack_dns_image }}" + +# Check that custom flavors are available +- include: custom_flavor_check.yaml +  with_items: +  - "{{ openshift_openstack_master_flavor }}" +  - "{{ openshift_openstack_infra_flavor }}" +  - "{{ openshift_openstack_node_flavor }}" +  - "{{ openshift_openstack_lb_flavor }}" +  - "{{ openshift_openstack_etcd_flavor }}" +  - "{{ openshift_openstack_dns_flavor }}" diff --git a/roles/openshift_openstack/tasks/cleanup.yml b/roles/openshift_openstack/tasks/cleanup.yml new file mode 100644 index 000000000..258334a6b --- /dev/null +++ b/roles/openshift_openstack/tasks/cleanup.yml @@ -0,0 +1,6 @@ +--- + +- name: cleanup temp files +  file: +    path: "{{ stack_template_pre.path }}" +    state: absent diff --git a/roles/openshift_openstack/tasks/container-storage-setup.yml b/roles/openshift_openstack/tasks/container-storage-setup.yml new file mode 100644 index 000000000..82307b208 --- /dev/null +++ b/roles/openshift_openstack/tasks/container-storage-setup.yml @@ -0,0 +1,37 @@ +--- +- block: +    - name: create the docker-storage config file +      template: +        src: docker-storage-setup-overlayfs.j2 +        dest: /etc/sysconfig/docker-storage-setup +        owner: root +        group: root +        mode: 0644 +  when: +    - ansible_distribution_version | version_compare('7.4', '>=') +    - ansible_distribution == "RedHat" + +- block: +    - name: create the docker-storage-setup config file +      template: +        src: docker-storage-setup-dm.j2 +        dest: /etc/sysconfig/docker-storage-setup +        owner: root +        group: root +        mode: 0644 +  when: +    - ansible_distribution_version | version_compare('7.4', '<') +    - ansible_distribution == "RedHat" + +- block: +    - name: create the docker-storage-setup config file for CentOS +      template: +        src: docker-storage-setup-dm.j2 +        dest: /etc/sysconfig/docker-storage-setup +        owner: root +        group: root +        mode: 0644 + +  # TODO(shadower): Find out which CentOS version supports overlayfs2 +  when: +    - ansible_distribution == "CentOS" diff --git a/roles/openshift_openstack/tasks/custom_flavor_check.yaml b/roles/openshift_openstack/tasks/custom_flavor_check.yaml new file mode 100644 index 000000000..5fb7a76ff --- /dev/null +++ b/roles/openshift_openstack/tasks/custom_flavor_check.yaml @@ -0,0 +1,10 @@ +--- +- name: Try to get flavor facts +  os_flavor_facts: +    name: "{{ item }}" +  register: flavor_result + +- name: Check that custom flavor is available +  assert: +    that: "flavor_result.ansible_facts.openstack_flavors" +    msg: "Flavor {{ item }} is not available." diff --git a/roles/openshift_openstack/tasks/custom_image_check.yaml b/roles/openshift_openstack/tasks/custom_image_check.yaml new file mode 100644 index 000000000..4ae163406 --- /dev/null +++ b/roles/openshift_openstack/tasks/custom_image_check.yaml @@ -0,0 +1,10 @@ +--- +- name: Try to get image facts +  os_image_facts: +    image: "{{ item }}" +  register: image_result + +- name: Check that custom image is available +  assert: +    that: "image_result.ansible_facts.openstack_image" +    msg: "Image {{ item }} is not available." diff --git a/roles/openshift_openstack/tasks/generate-templates.yml b/roles/openshift_openstack/tasks/generate-templates.yml new file mode 100644 index 000000000..3a8b588e9 --- /dev/null +++ b/roles/openshift_openstack/tasks/generate-templates.yml @@ -0,0 +1,29 @@ +--- +- name: create HOT stack template prefix +  register: stack_template_pre +  tempfile: +    state: directory +    prefix: openshift-ansible + +- name: set template paths +  set_fact: +    stack_template_path: "{{ stack_template_pre.path }}/stack.yaml" +    user_data_template_path: "{{ stack_template_pre.path }}/user-data" + +- name: Print out the Heat template directory +  debug: var=stack_template_pre + +- name: generate HOT stack template from jinja2 template +  template: +    src: heat_stack.yaml.j2 +    dest: "{{ stack_template_path }}" + +- name: generate HOT server template from jinja2 template +  template: +    src: heat_stack_server.yaml.j2 +    dest: "{{ stack_template_pre.path }}/server.yaml" + +- name: generate user_data from jinja2 template +  template: +    src: user_data.j2 +    dest: "{{ user_data_template_path }}" diff --git a/roles/openshift_openstack/tasks/hostname.yml b/roles/openshift_openstack/tasks/hostname.yml new file mode 100644 index 000000000..e1a18425f --- /dev/null +++ b/roles/openshift_openstack/tasks/hostname.yml @@ -0,0 +1,26 @@ +--- +- name: Setting Hostname Fact +  set_fact: +    new_hostname: "{{ custom_hostname | default(inventory_hostname_short) }}" + +- name: Setting FQDN Fact +  set_fact: +    new_fqdn: "{{ new_hostname }}.{{ openshift_openstack_full_dns_domain }}" + +- name: Setting hostname and DNS domain +  hostname: name="{{ new_fqdn }}" + +- name: Check for cloud.cfg +  stat: path=/etc/cloud/cloud.cfg +  register: cloud_cfg + +- name: Prevent cloud-init updates of hostname/fqdn (if applicable) +  lineinfile: +    dest: /etc/cloud/cloud.cfg +    state: present +    regexp: "{{ item.regexp }}" +    line: "{{ item.line }}" +  with_items: +  - { regexp: '^ - set_hostname', line: '# - set_hostname' } +  - { regexp: '^ - update_hostname', line: '# - update_hostname' } +  when: cloud_cfg.stat.exists == True diff --git a/roles/openshift_openstack/tasks/net_vars_check.yaml b/roles/openshift_openstack/tasks/net_vars_check.yaml new file mode 100644 index 000000000..18b9b21b9 --- /dev/null +++ b/roles/openshift_openstack/tasks/net_vars_check.yaml @@ -0,0 +1,14 @@ +--- +- name: Check the provider network configuration +  fail: +    msg: "Flannel SDN requires a dedicated containers data network and can not work over a provider network" +  when: +    - openshift_openstack_provider_network_name is defined +    - openstack_private_data_network_name is defined + +- name: Check the flannel network configuration +  fail: +    msg: "A dedicated containers data network is only supported with Flannel SDN" +  when: +    - openstack_private_data_network_name is defined +    - not openshift_use_flannel|default(False)|bool diff --git a/roles/openshift_openstack/tasks/node-configuration.yml b/roles/openshift_openstack/tasks/node-configuration.yml new file mode 100644 index 000000000..89e58d830 --- /dev/null +++ b/roles/openshift_openstack/tasks/node-configuration.yml @@ -0,0 +1,11 @@ +--- +- name: "Verify SELinux is enforcing" +  fail: +    msg: "SELinux is required for OpenShift and has been detected as '{{ ansible_selinux.config_mode }}'" +  when: ansible_selinux.config_mode != "enforcing" + +- include: hostname.yml + +- include: container-storage-setup.yml + +- include: node-network.yml diff --git a/roles/openshift_openstack/tasks/node-network.yml b/roles/openshift_openstack/tasks/node-network.yml new file mode 100644 index 000000000..f494e5158 --- /dev/null +++ b/roles/openshift_openstack/tasks/node-network.yml @@ -0,0 +1,19 @@ +--- +- name: configure NetworkManager +  lineinfile: +    dest: "/etc/sysconfig/network-scripts/ifcfg-{{ ansible_default_ipv4['interface'] }}" +    regexp: '^{{ item }}=' +    line: '{{ item }}=yes' +    state: present +    create: yes +  with_items: +  - 'USE_PEERDNS' +  - 'NM_CONTROLLED' + +- name: enable and start NetworkManager +  service: +    name: NetworkManager +    state: restarted +    enabled: yes + +# TODO(shadower): add the flannel interface tasks from post-provision-openstack.yml diff --git a/roles/openshift_openstack/tasks/node-packages.yml b/roles/openshift_openstack/tasks/node-packages.yml new file mode 100644 index 000000000..7864f5269 --- /dev/null +++ b/roles/openshift_openstack/tasks/node-packages.yml @@ -0,0 +1,15 @@ +--- +# TODO: subscribe to RHEL and install docker and other packages here + +- name: Install required packages +  yum: +    name: "{{ item }}" +    state: latest +  with_items: "{{ openshift_openstack_required_packages }}" + +- name: Install debug packages (optional) +  yum: +    name: "{{ item }}" +    state: latest +  with_items: "{{ openshift_openstack_debug_packages }}" +  when: openshift_openstack_install_debug_packages|bool diff --git a/roles/openshift_openstack/tasks/populate-dns.yml b/roles/openshift_openstack/tasks/populate-dns.yml new file mode 100644 index 000000000..c03aceb94 --- /dev/null +++ b/roles/openshift_openstack/tasks/populate-dns.yml @@ -0,0 +1,128 @@ +--- +- name: "Generate list of private A records" +  set_fact: +    private_records: "{{ private_records | default([]) + [ { 'type': 'A', 'hostname': hostvars[item]['ansible_hostname'], 'ip': hostvars[item]['private_v4'] } ] }}" +  with_items: "{{ groups['cluster_hosts'] }}" + +- name: "Add wildcard records to the private A records for infrahosts" +  set_fact: +    private_records: "{{ private_records | default([]) + [ { 'type': 'A', 'hostname': '*.' + openshift_openstack_app_subdomain, 'ip': hostvars[item]['private_v4'] } ] }}" +  with_items: "{{ groups['infra_hosts'] }}" + +- name: "Add public master cluster hostname records to the private A records (single master)" +  set_fact: +    private_records: "{{ private_records | default([]) + [ { 'type': 'A', 'hostname': (hostvars[groups.masters[0]].openshift_master_cluster_public_hostname | replace(openshift_openstack_full_dns_domain, ''))[:-1], 'ip': hostvars[groups.masters[0]].private_v4 } ] }}" +  when: +    - hostvars[groups.masters[0]].openshift_master_cluster_public_hostname is defined +    - openshift_openstack_num_masters == 1 + +- name: "Add public master cluster hostname records to the private A records (multi-master)" +  set_fact: +    private_records: "{{ private_records | default([]) + [ { 'type': 'A', 'hostname': (hostvars[groups.masters[0]].openshift_master_cluster_public_hostname | replace(openshift_openstack_full_dns_domain, ''))[:-1], 'ip': hostvars[groups.lb[0]].private_v4 } ] }}" +  when: +    - hostvars[groups.masters[0]].openshift_master_cluster_public_hostname is defined +    - openshift_openstack_num_masters > 1 + +- name: "Set the private DNS server to use the external value (if provided)" +  set_fact: +    nsupdate_server_private: "{{ openshift_openstack_external_nsupdate_keys['private']['server'] }}" +    nsupdate_key_secret_private: "{{ openshift_openstack_external_nsupdate_keys['private']['key_secret'] }}" +    nsupdate_key_algorithm_private: "{{ openshift_openstack_external_nsupdate_keys['private']['key_algorithm'] }}" +    nsupdate_private_key_name: "{{ openshift_openstack_external_nsupdate_keys['private']['key_name']|default('private-' + openshift_openstack_full_dns_domain) }}" +  when: +    - openshift_openstack_external_nsupdate_keys is defined +    - openshift_openstack_external_nsupdate_keys['private'] is defined + + +- name: "Generate the private Add section for DNS" +  set_fact: +    private_named_records: +      - view: "private" +        zone: "{{ openshift_openstack_full_dns_domain }}" +        server: "{{ nsupdate_server_private }}" +        key_name: "{{ nsupdate_private_key_name|default('private-' + openshift_openstack_full_dns_domain) }}" +        key_secret: "{{ nsupdate_key_secret_private }}" +        key_algorithm: "{{ nsupdate_key_algorithm_private | lower }}" +        entries: "{{ private_records }}" + +- name: "Generate list of public A records" +  set_fact: +    public_records: "{{ public_records | default([]) + [ { 'type': 'A', 'hostname': hostvars[item]['ansible_hostname'], 'ip': hostvars[item]['public_v4'] } ] }}" +  with_items: "{{ groups['cluster_hosts'] }}" +  when: hostvars[item]['public_v4'] is defined + +- name: "Add wildcard records to the public A records" +  set_fact: +    public_records: "{{ public_records | default([]) + [ { 'type': 'A', 'hostname': '*.' + openshift_openstack_app_subdomain, 'ip': hostvars[item]['public_v4'] } ] }}" +  with_items: "{{ groups['infra_hosts'] }}" +  when: hostvars[item]['public_v4'] is defined + +- name: "Add public master cluster hostname records to the public A records (single master)" +  set_fact: +    public_records: "{{ public_records | default([]) + [ { 'type': 'A', 'hostname': (hostvars[groups.masters[0]].openshift_master_cluster_public_hostname | replace(openshift_openstack_full_dns_domain, ''))[:-1], 'ip': hostvars[groups.masters[0]].public_v4 } ] }}" +  when: +    - hostvars[groups.masters[0]].openshift_master_cluster_public_hostname is defined +    - openshift_openstack_num_masters == 1 +    - not openshift_openstack_use_bastion|bool + +- name: "Add public master cluster hostname records to the public A records (single master behind a bastion)" +  set_fact: +    public_records: "{{ public_records | default([]) + [ { 'type': 'A', 'hostname': (hostvars[groups.masters[0]].openshift_master_cluster_public_hostname | replace(openshift_openstack_full_dns_domain, ''))[:-1], 'ip': hostvars[groups.bastions[0]].public_v4 } ] }}" +  when: +    - hostvars[groups.masters[0]].openshift_master_cluster_public_hostname is defined +    - openshift_openstack_num_masters == 1 +    - openshift_openstack_use_bastion|bool + +- name: "Add public master cluster hostname records to the public A records (multi-master)" +  set_fact: +    public_records: "{{ public_records | default([]) + [ { 'type': 'A', 'hostname': (hostvars[groups.masters[0]].openshift_master_cluster_public_hostname | replace(openshift_openstack_full_dns_domain, ''))[:-1], 'ip': hostvars[groups.lb[0]].public_v4 } ] }}" +  when: +    - hostvars[groups.masters[0]].openshift_master_cluster_public_hostname is defined +    - openshift_openstack_num_masters > 1 + +- name: "Set the public DNS server details to use the external value (if provided)" +  set_fact: +    nsupdate_server_public: "{{ openshift_openstack_external_nsupdate_keys['public']['server'] }}" +    nsupdate_key_secret_public: "{{ openshift_openstack_external_nsupdate_keys['public']['key_secret'] }}" +    nsupdate_key_algorithm_public: "{{ openshift_openstack_external_nsupdate_keys['public']['key_algorithm'] }}" +    nsupdate_public_key_name: "{{ openshift_openstack_external_nsupdate_keys['public']['key_name']|default('public-' + openshift_openstack_full_dns_domain) }}" +  when: +    - openshift_openstack_external_nsupdate_keys is defined +    - openshift_openstack_external_nsupdate_keys['public'] is defined + +- name: "Generate the public Add section for DNS" +  set_fact: +    public_named_records: +      - view: "public" +        zone: "{{ openshift_openstack_full_dns_domain }}" +        server: "{{ nsupdate_server_public }}" +        key_name: "{{ nsupdate_public_key_name|default('public-' + openshift_openstack_full_dns_domain) }}" +        key_secret: "{{ nsupdate_key_secret_public }}" +        key_algorithm: "{{ nsupdate_key_algorithm_public | lower }}" +        entries: "{{ public_records }}" + + +- name: "Generate the final openshift_openstack_dns_records_add" +  set_fact: +    openshift_openstack_dns_records_add: "{{ private_named_records + public_named_records }}" + + +- name: "Add DNS A records" +  nsupdate: +    key_name: "{{ item.0.key_name }}" +    key_secret: "{{ item.0.key_secret }}" +    key_algorithm: "{{ item.0.key_algorithm }}" +    server: "{{ item.0.server }}" +    zone: "{{ item.0.zone }}" +    record: "{{ item.1.hostname }}" +    value: "{{ item.1.ip }}" +    type: "{{ item.1.type }}" +    # TODO(shadower): add a cleanup playbook that removes these records, too! +    state: present +  with_subelements: +    - "{{ openshift_openstack_dns_records_add | default({}) }}" +    - entries +  register: nsupdate_add_result +  until: nsupdate_add_result|succeeded +  retries: 10 +  delay: 1 diff --git a/roles/openshift_openstack/tasks/prepare-and-format-cinder-volume.yaml b/roles/openshift_openstack/tasks/prepare-and-format-cinder-volume.yaml new file mode 100644 index 000000000..fc51f6dc2 --- /dev/null +++ b/roles/openshift_openstack/tasks/prepare-and-format-cinder-volume.yaml @@ -0,0 +1,59 @@ +--- +- name: Attach the volume to the VM +  os_server_volume: +    state: present +    server: "{{ groups['masters'][0] }}" +    volume: "{{ cinder_volume }}" +  register: volume_attachment + +- set_fact: +    attached_device: >- +      {{ volume_attachment['attachments']|json_query("[?volume_id=='" + cinder_volume + "'].device | [0]") }} + +- delegate_to: "{{ groups['masters'][0] }}" +  block: +  - name: Wait for the device to appear +    wait_for: path={{ attached_device }} + +  - name: Create a temp directory for mounting the volume +    tempfile: +      prefix: cinder-volume +      state: directory +    register: cinder_mount_dir + +  - name: Format the device +    filesystem: +      fstype: "{{ cinder_fs }}" +      dev: "{{ attached_device }}" + +  - name: Mount the device +    mount: +      name: "{{ cinder_mount_dir.path }}" +      src: "{{ attached_device }}" +      state: mounted +      fstype: "{{ cinder_fs }}" + +  - name: Change mode on the filesystem +    file: +      path: "{{ cinder_mount_dir.path }}" +      state: directory +      recurse: true +      mode: 0777 + +  - name: Unmount the device +    mount: +      name: "{{ cinder_mount_dir.path }}" +      src: "{{ attached_device }}" +      state: absent +      fstype: "{{ cinder_fs }}" + +  - name: Delete the temp directory +    file: +      name: "{{ cinder_mount_dir.path }}" +      state: absent + +- name: Detach the volume from the VM +  os_server_volume: +    state: absent +    server: "{{ groups['masters'][0] }}" +    volume: "{{ cinder_volume }}" diff --git a/roles/openshift_openstack/tasks/provision.yml b/roles/openshift_openstack/tasks/provision.yml new file mode 100644 index 000000000..dccbe334c --- /dev/null +++ b/roles/openshift_openstack/tasks/provision.yml @@ -0,0 +1,25 @@ +--- +- name: Generate the templates +  include: generate-templates.yml +  when: +  - openshift_openstack_stack_state == 'present' + +- name: Handle the Stack (create/delete) +  ignore_errors: False +  register: stack_create +  os_stack: +    name: "{{ openshift_openstack_stack_name }}" +    state: "{{ openshift_openstack_stack_state }}" +    template: "{{ stack_template_path | default(omit) }}" +    wait: yes + +- name: Add the new nodes to the inventory +  meta: refresh_inventory + +- name: CleanUp +  include: cleanup.yml +  when: +  - openshift_openstack_stack_state == 'present' + +# TODO(shadower): create the registry and PV Cinder volumes if specified +# and include the `prepare-and-format-cinder-volume` tasks to set it up diff --git a/roles/openshift_openstack/templates/docker-storage-setup-dm.j2 b/roles/openshift_openstack/templates/docker-storage-setup-dm.j2 new file mode 100644 index 000000000..32c6b5838 --- /dev/null +++ b/roles/openshift_openstack/templates/docker-storage-setup-dm.j2 @@ -0,0 +1,4 @@ +DEVS="{{ openshift_openstack_container_storage_setup.docker_dev }}" +VG="{{ openshift_openstack_container_storage_setup.docker_vg }}" +DATA_SIZE="{{ openshift_openstack_container_storage_setup.docker_data_size }}" +EXTRA_DOCKER_STORAGE_OPTIONS="--storage-opt dm.basesize={{ openshift_openstack_container_storage_setup.docker_dm_basesize }}" diff --git a/roles/openshift_openstack/templates/docker-storage-setup-overlayfs.j2 b/roles/openshift_openstack/templates/docker-storage-setup-overlayfs.j2 new file mode 100644 index 000000000..1bf366bdc --- /dev/null +++ b/roles/openshift_openstack/templates/docker-storage-setup-overlayfs.j2 @@ -0,0 +1,7 @@ +DEVS="{{ openshift_openstack_container_storage_setup.docker_dev }}" +VG="{{ openshift_openstack_container_storage_setup.docker_vg }}" +DATA_SIZE="{{ openshift_openstack_container_storage_setup.docker_data_size }}" +STORAGE_DRIVER=overlay2 +CONTAINER_ROOT_LV_NAME="{{ openshift_openstack_container_storage_setup.container_root_lv_name }}" +CONTAINER_ROOT_LV_MOUNT_PATH="{{ openshift_openstack_container_storage_setup.container_root_lv_mount_path }}" +CONTAINER_ROOT_LV_SIZE=100%FREE diff --git a/roles/openshift_openstack/templates/heat_stack.yaml.j2 b/roles/openshift_openstack/templates/heat_stack.yaml.j2 new file mode 100644 index 000000000..bfa65b460 --- /dev/null +++ b/roles/openshift_openstack/templates/heat_stack.yaml.j2 @@ -0,0 +1,888 @@ +heat_template_version: 2016-10-14 + +description: OpenShift cluster + +parameters: + +outputs: + +  etcd_names: +    description: Name of the etcds +    value: { get_attr: [ etcd, name ] } + +  etcd_ips: +    description: IPs of the etcds +    value: { get_attr: [ etcd, private_ip ] } + +  etcd_floating_ips: +    description: Floating IPs of the etcds +    value: { get_attr: [ etcd, floating_ip ] } + +  master_names: +    description: Name of the masters +    value: { get_attr: [ masters, name ] } + +  master_ips: +    description: IPs of the masters +    value: { get_attr: [ masters, private_ip ] } + +  master_floating_ips: +    description: Floating IPs of the masters +    value: { get_attr: [ masters, floating_ip ] } + +  node_names: +    description: Name of the nodes +    value: { get_attr: [ compute_nodes, name ] } + +  node_ips: +    description: IPs of the nodes +    value: { get_attr: [ compute_nodes, private_ip ] } + +  node_floating_ips: +    description: Floating IPs of the nodes +    value: { get_attr: [ compute_nodes, floating_ip ] } + +  infra_names: +    description: Name of the nodes +    value: { get_attr: [ infra_nodes, name ] } + +  infra_ips: +    description: IPs of the nodes +    value: { get_attr: [ infra_nodes, private_ip ] } + +  infra_floating_ips: +    description: Floating IPs of the nodes +    value: { get_attr: [ infra_nodes, floating_ip ] } + +{% if openshift_openstack_num_dns|int > 0 %} +  dns_name: +    description: Name of the DNS +    value: +      get_attr: +        - dns +        - name + +  dns_floating_ips: +    description: Floating IPs of the DNS +    value: { get_attr: [ dns, floating_ip ] } + +  dns_private_ips: +    description: Private IPs of the DNS +    value: { get_attr: [ dns, private_ip ] } +{% endif %} + +conditions: +  no_floating: {% if openshift_openstack_provider_network_name or openshift_openstack_use_bastion|bool %}true{% else %}false{% endif %} + +resources: + +{% if not openshift_openstack_provider_network_name %} +  net: +    type: OS::Neutron::Net +    properties: +      name: +        str_replace: +          template: openshift-ansible-cluster_id-net +          params: +            cluster_id: {{ openshift_openstack_stack_name }} + +  subnet: +    type: OS::Neutron::Subnet +    properties: +      name: +        str_replace: +          template: openshift-ansible-cluster_id-subnet +          params: +            cluster_id: {{ openshift_openstack_stack_name }} +      network: { get_resource: net } +      cidr: +        str_replace: +          template: subnet_24_prefix.0/24 +          params: +            subnet_24_prefix: {{ openshift_openstack_subnet_prefix }} +      allocation_pools: +        - start: +            str_replace: +              template: subnet_24_prefix.3 +              params: +                subnet_24_prefix: {{ openshift_openstack_subnet_prefix }} +          end: +            str_replace: +              template: subnet_24_prefix.254 +              params: +                subnet_24_prefix: {{ openshift_openstack_subnet_prefix }} +      dns_nameservers: +{% for nameserver in openshift_openstack_dns_nameservers %} +        - {{ nameserver }} +{% endfor %} + +{% if openshift_use_flannel|default(False)|bool %} +  data_net: +    type: OS::Neutron::Net +    properties: +      name: openshift-ansible-{{ openshift_openstack_stack_name }}-data-net +      port_security_enabled: false + +  data_subnet: +    type: OS::Neutron::Subnet +    properties: +      name: openshift-ansible-{{ openshift_openstack_stack_name }}-data-subnet +      network: { get_resource: data_net } +      cidr: {{ osm_cluster_network_cidr|default('10.128.0.0/14') }} +      gateway_ip: null +{% endif %} + +  router: +    type: OS::Neutron::Router +    properties: +      name: +        str_replace: +          template: openshift-ansible-cluster_id-router +          params: +            cluster_id: {{ openshift_openstack_stack_name }} +      external_gateway_info: +        network: {{ openshift_openstack_external_network_name }} + +  interface: +    type: OS::Neutron::RouterInterface +    properties: +      router_id: { get_resource: router } +      subnet_id: { get_resource: subnet } + +{% endif %} + +#  keypair: +#    type: OS::Nova::KeyPair +#    properties: +#      name: +#        str_replace: +#          template: openshift-ansible-cluster_id-keypair +#          params: +#            cluster_id: {{ openshift_openstack_stack_name }} +#      public_key: {{ openshift_openstack_keypair_name }} + +  common-secgrp: +    type: OS::Neutron::SecurityGroup +    properties: +      name: +        str_replace: +          template: openshift-ansible-cluster_id-common-secgrp +          params: +            cluster_id: {{ openshift_openstack_stack_name }} +      description: +        str_replace: +          template: Basic ssh/icmp security group for cluster_id OpenShift cluster +          params: +            cluster_id: {{ openshift_openstack_stack_name }} +      rules: +        - direction: ingress +          protocol: tcp +          port_range_min: 22 +          port_range_max: 22 +          remote_ip_prefix: {{ openshift_openstack_ssh_ingress_cidr }} +{% if openshift_openstack_use_bastion|bool %} +        - direction: ingress +          protocol: tcp +          port_range_min: 22 +          port_range_max: 22 +          remote_ip_prefix: {{ openshift_openstack_bastion_ingress_cidr }} +{% endif %} +        - direction: ingress +          protocol: icmp +          remote_ip_prefix: {{ openshift_openstack_ssh_ingress_cidr }} + +{% if openshift_openstack_flat_secgrp|default(False)|bool %} +  flat-secgrp: +    type: OS::Neutron::SecurityGroup +    properties: +      name: +        str_replace: +          template: openshift-ansible-cluster_id-flat-secgrp +          params: +            cluster_id: {{ openshift_openstack_stack_name }} +      description: +        str_replace: +          template: Security group for cluster_id OpenShift cluster +          params: +            cluster_id: {{ openshift_openstack_stack_name }} +      rules: +        - direction: ingress +          protocol: tcp +          port_range_min: 4001 +          port_range_max: 4001 +        - direction: ingress +          protocol: tcp +          port_range_min: {{ openshift_master_api_port|default(8443) }} +          port_range_max: {{ openshift_master_api_port|default(8443) }} +        - direction: ingress +          protocol: tcp +          port_range_min: {{ openshift_master_console_port|default(8443) }} +          port_range_max: {{ openshift_master_console_port|default(8443) }} +        - direction: ingress +          protocol: tcp +          port_range_min: 8053 +          port_range_max: 8053 +        - direction: ingress +          protocol: udp +          port_range_min: 8053 +          port_range_max: 8053 +        - direction: ingress +          protocol: tcp +          port_range_min: 24224 +          port_range_max: 24224 +        - direction: ingress +          protocol: udp +          port_range_min: 24224 +          port_range_max: 24224 +        - direction: ingress +          protocol: tcp +          port_range_min: 2224 +          port_range_max: 2224 +        - direction: ingress +          protocol: udp +          port_range_min: 5404 +          port_range_max: 5405 +        - direction: ingress +          protocol: tcp +          port_range_min: 9090 +          port_range_max: 9090 +        - direction: ingress +          protocol: tcp +          port_range_min: 2379 +          port_range_max: 2380 +          remote_mode: remote_group_id +        - direction: ingress +          protocol: tcp +          port_range_min: 10250 +          port_range_max: 10250 +          remote_mode: remote_group_id +        - direction: ingress +          protocol: udp +          port_range_min: 10250 +          port_range_max: 10250 +          remote_mode: remote_group_id +        - direction: ingress +          protocol: tcp +          port_range_min: 10255 +          port_range_max: 10255 +          remote_mode: remote_group_id +        - direction: ingress +          protocol: udp +          port_range_min: 10255 +          port_range_max: 10255 +          remote_mode: remote_group_id +        - direction: ingress +          protocol: udp +          port_range_min: 4789 +          port_range_max: 4789 +          remote_mode: remote_group_id +        - direction: ingress +          protocol: tcp +          port_range_min: 30000 +          port_range_max: 32767 +          remote_ip_prefix: {{ openshift_openstack_node_ingress_cidr }} +        - direction: ingress +          protocol: tcp +          port_range_min: 30000 +          port_range_max: 32767 +          remote_ip_prefix: "{{ openshift_openstack_subnet_prefix }}.0/24" +{% else %} +  master-secgrp: +    type: OS::Neutron::SecurityGroup +    properties: +      name: +        str_replace: +          template: openshift-ansible-cluster_id-master-secgrp +          params: +            cluster_id: {{ openshift_openstack_stack_name }} +      description: +        str_replace: +          template: Security group for cluster_id OpenShift cluster master +          params: +            cluster_id: {{ openshift_openstack_stack_name }} +      rules: +        - direction: ingress +          protocol: tcp +          port_range_min: 4001 +          port_range_max: 4001 +        - direction: ingress +          protocol: tcp +          port_range_min: {{ openshift_master_api_port|default(8443) }} +          port_range_max: {{ openshift_master_api_port|default(8443) }} +        - direction: ingress +          protocol: tcp +          port_range_min: {{ openshift_master_console_port|default(8443) }} +          port_range_max: {{ openshift_master_console_port|default(8443) }} +        - direction: ingress +          protocol: tcp +          port_range_min: 8053 +          port_range_max: 8053 +        - direction: ingress +          protocol: udp +          port_range_min: 8053 +          port_range_max: 8053 +        - direction: ingress +          protocol: tcp +          port_range_min: 24224 +          port_range_max: 24224 +        - direction: ingress +          protocol: udp +          port_range_min: 24224 +          port_range_max: 24224 +        - direction: ingress +          protocol: tcp +          port_range_min: 2224 +          port_range_max: 2224 +        - direction: ingress +          protocol: udp +          port_range_min: 5404 +          port_range_max: 5405 +        - direction: ingress +          protocol: tcp +          port_range_min: 9090 +          port_range_max: 9090 +{% if openshift_use_flannel|default(False)|bool %} +        - direction: ingress +          protocol: tcp +          port_range_min: 2379 +          port_range_max: 2379 +{% endif %} + +  etcd-secgrp: +    type: OS::Neutron::SecurityGroup +    properties: +      name: +        str_replace: +          template: openshift-ansible-cluster_id-etcd-secgrp +          params: +            cluster_id: {{ openshift_openstack_stack_name }} +      description: +        str_replace: +          template: Security group for cluster_id etcd cluster +          params: +            cluster_id: {{ openshift_openstack_stack_name }} +      rules: +        - direction: ingress +          protocol: tcp +          port_range_min: 2379 +          port_range_max: 2379 +          remote_mode: remote_group_id +          remote_group_id: { get_resource: master-secgrp } +        - direction: ingress +          protocol: tcp +          port_range_min: 2380 +          port_range_max: 2380 +          remote_mode: remote_group_id + +  node-secgrp: +    type: OS::Neutron::SecurityGroup +    properties: +      name: +        str_replace: +          template: openshift-ansible-cluster_id-node-secgrp +          params: +            cluster_id: {{ openshift_openstack_stack_name }} +      description: +        str_replace: +          template: Security group for cluster_id OpenShift cluster nodes +          params: +            cluster_id: {{ openshift_openstack_stack_name }} +      rules: +        - direction: ingress +          protocol: tcp +          port_range_min: 10250 +          port_range_max: 10250 +          remote_mode: remote_group_id +        - direction: ingress +          protocol: tcp +          port_range_min: 10255 +          port_range_max: 10255 +          remote_mode: remote_group_id +        - direction: ingress +          protocol: udp +          port_range_min: 10255 +          port_range_max: 10255 +          remote_mode: remote_group_id +        - direction: ingress +          protocol: udp +          port_range_min: 4789 +          port_range_max: 4789 +          remote_mode: remote_group_id +        - direction: ingress +          protocol: tcp +          port_range_min: 30000 +          port_range_max: 32767 +          remote_ip_prefix: {{ openshift_openstack_node_ingress_cidr }} +        - direction: ingress +          protocol: tcp +          port_range_min: 30000 +          port_range_max: 32767 +          remote_ip_prefix: "{{ openshift_openstack_subnet_prefix }}.0/24" +{% endif %} + +  infra-secgrp: +    type: OS::Neutron::SecurityGroup +    properties: +      name: +        str_replace: +          template: openshift-ansible-cluster_id-infra-secgrp +          params: +            cluster_id: {{ openshift_openstack_stack_name }} +      description: +        str_replace: +          template: Security group for cluster_id OpenShift infrastructure cluster nodes +          params: +            cluster_id: {{ openshift_openstack_stack_name }} +      rules: +        - direction: ingress +          protocol: tcp +          port_range_min: 80 +          port_range_max: 80 +        - direction: ingress +          protocol: tcp +          port_range_min: 443 +          port_range_max: 443 + +{% if openshift_openstack_num_dns|int > 0 %} +  dns-secgrp: +    type: OS::Neutron::SecurityGroup +    properties: +      name: +        str_replace: +          template: openshift-ansible-cluster_id-dns-secgrp +          params: +            cluster_id: {{ openshift_openstack_stack_name }} +      description: +        str_replace: +          template: Security group for cluster_id cluster DNS +          params: +            cluster_id: {{ openshift_openstack_stack_name }} +      rules: +        - direction: ingress +          protocol: udp +          port_range_min: 53 +          port_range_max: 53 +          remote_ip_prefix: {{ openshift_openstack_node_ingress_cidr }} +        - direction: ingress +          protocol: udp +          port_range_min: 53 +          port_range_max: 53 +          remote_ip_prefix: "{{ openshift_openstack_subnet_prefix }}.0/24" +        - direction: ingress +          protocol: tcp +          port_range_min: 53 +          port_range_max: 53 +          remote_ip_prefix: {{ openshift_openstack_node_ingress_cidr }} +        - direction: ingress +          protocol: tcp +          port_range_min: 53 +          port_range_max: 53 +          remote_ip_prefix: "{{ openshift_openstack_subnet_prefix }}.0/24" +{% endif %} + +{% if openshift_openstack_num_masters|int > 1 or openshift_openstack_ui_ssh_tunnel|bool %} +  lb-secgrp: +    type: OS::Neutron::SecurityGroup +    properties: +      name: openshift-ansible-{{ openshift_openstack_stack_name }}-lb-secgrp +      description: Security group for {{ openshift_openstack_stack_name }} cluster Load Balancer +      rules: +      - direction: ingress +        protocol: tcp +        port_range_min: {{ openshift_master_api_port | default(8443) }} +        port_range_max: {{ openshift_master_api_port | default(8443) }} +        remote_ip_prefix: {{ openshift_openstack_lb_ingress_cidr | default(openshift_openstack_bastion_ingress_cidr) }} +{% if openshift_openstack_ui_ssh_tunnel|bool %} +      - direction: ingress +        protocol: tcp +        port_range_min: {{ openshift_master_api_port | default(8443) }} +        port_range_max: {{ openshift_master_api_port | default(8443) }} +        remote_ip_prefix: {{ openshift_openstack_ssh_ingress_cidr }} +{% endif %} +{% if openshift_master_console_port is defined and openshift_master_console_port != openshift_master_api_port %} +      - direction: ingress +        protocol: tcp +        port_range_min: {{ openshift_master_console_port | default(8443) }} +        port_range_max: {{ openshift_master_console_port | default(8443) }} +        remote_ip_prefix: {{ openshift_openstack_lb_ingress_cidr | default(openshift_openstack_bastion_ingress_cidr) }} +{% endif %} +{% endif %} + +  etcd: +    type: OS::Heat::ResourceGroup +    properties: +      count: {{ openshift_openstack_num_etcd }} +      resource_def: +        type: server.yaml +        properties: +          name: +            str_replace: +              template: k8s_type-%index%.cluster_id +              params: +                cluster_id: {{ openshift_openstack_stack_name }} +                k8s_type: {{ openshift_openstack_etcd_hostname }} +          cluster_env: {{ openshift_openstack_public_dns_domain }} +          cluster_id:  {{ openshift_openstack_stack_name }} +          group: +            str_replace: +              template: k8s_type.cluster_id +              params: +                k8s_type: etcds +                cluster_id: {{ openshift_openstack_stack_name }} +          type:        etcd +          image:       {{ openshift_openstack_etcd_image }} +          flavor:      {{ openshift_openstack_etcd_flavor }} +          key_name:    {{ openshift_openstack_keypair_name }} +{% if openshift_openstack_provider_network_name %} +          net:         {{ openshift_openstack_provider_network_name }} +          net_name:         {{ openshift_openstack_provider_network_name }} +{% else %} +          net:         { get_resource: net } +          subnet:      { get_resource: subnet } +          net_name: +            str_replace: +              template: openshift-ansible-cluster_id-net +              params: +                cluster_id: {{ openshift_openstack_stack_name }} +{% endif %} +          secgrp: +            - { get_resource: {% if openshift_openstack_flat_secgrp|default(False)|bool %}flat-secgrp{% else %}etcd-secgrp{% endif %} } +            - { get_resource: common-secgrp } +          floating_network: +            if: +              - no_floating +              - null +              - {{ openshift_openstack_external_network_name }} +{% if openshift_openstack_use_bastion|bool or openshift_openstack_provider_network_name %} +          attach_float_net: false +{% endif %} +          volume_size: {{ openshift_openstack_etcd_volume_size }} +{% if not openshift_openstack_provider_network_name %} +    depends_on: +      - interface +{% endif %} + +{% if openshift_openstack_master_server_group_policies|length > 0 %} +  master_server_group: +    type: OS::Nova::ServerGroup +    properties: +      name: master_server_group +      policies: {{ openshift_openstack_master_server_group_policies }} +{% endif %} +{% if openshift_openstack_infra_server_group_policies|length > 0 %} +  infra_server_group: +    type: OS::Nova::ServerGroup +    properties: +      name: infra_server_group +      policies: {{ openshift_openstack_infra_server_group_policies }} +{% endif %} +{% if openshift_openstack_num_masters|int > 1 %} +  loadbalancer: +    type: OS::Heat::ResourceGroup +    properties: +      count: 1 +      resource_def: +        type: server.yaml +        properties: +          name: +            str_replace: +              template: k8s_type-%index%.cluster_id +              params: +                cluster_id: {{ openshift_openstack_stack_name }} +                k8s_type: {{ openshift_openstack_lb_hostname }} +          cluster_env: {{ openshift_openstack_public_dns_domain }} +          cluster_id:  {{ openshift_openstack_stack_name }} +          group: +            str_replace: +              template: k8s_type.cluster_id +              params: +                k8s_type: lb +                cluster_id: {{ openshift_openstack_stack_name }} +          type:        lb +          image:       {{ openshift_openstack_lb_image }} +          flavor:      {{ openshift_openstack_lb_flavor }} +          key_name:    {{ openshift_openstack_keypair_name }} +{% if openshift_openstack_provider_network_name %} +          net:         {{ openshift_openstack_provider_network_name }} +          net_name:         {{ openshift_openstack_provider_network_name }} +{% else %} +          net:         { get_resource: net } +          subnet:      { get_resource: subnet } +          net_name: +            str_replace: +              template: openshift-ansible-cluster_id-net +              params: +                cluster_id: {{ openshift_openstack_stack_name }} +{% endif %} +          secgrp: +            - { get_resource: lb-secgrp } +            - { get_resource: common-secgrp } +{% if not openshift_openstack_provider_network_name %} +          floating_network: {{ openshift_openstack_external_network_name }} +{% endif %} +          volume_size: {{ openshift_openstack_lb_volume_size }} +{% if not openshift_openstack_provider_network_name %} +    depends_on: +      - interface +{% endif %} +{% endif %} + +  masters: +    type: OS::Heat::ResourceGroup +    properties: +      count: {{ openshift_openstack_num_masters }} +      resource_def: +        type: server.yaml +        properties: +          name: +            str_replace: +              template: k8s_type-%index%.cluster_id +              params: +                cluster_id: {{ openshift_openstack_stack_name }} +                k8s_type: {{ openshift_openstack_master_hostname }} +          cluster_env: {{ openshift_openstack_public_dns_domain }} +          cluster_id:  {{ openshift_openstack_stack_name }} +          group: +            str_replace: +              template: k8s_type.cluster_id +              params: +                k8s_type: masters +                cluster_id: {{ openshift_openstack_stack_name }} +          type:        master +          image:       {{ openshift_openstack_master_image }} +          flavor:      {{ openshift_openstack_master_flavor }} +          key_name:    {{ openshift_openstack_keypair_name }} +{% if openshift_openstack_provider_network_name %} +          net:         {{ openshift_openstack_provider_network_name }} +          net_name:         {{ openshift_openstack_provider_network_name }} +{% else %} +          net:         { get_resource: net } +          subnet:      { get_resource: subnet } +          net_name: +            str_replace: +              template: openshift-ansible-cluster_id-net +              params: +                cluster_id: {{ openshift_openstack_stack_name }} +{% if openshift_use_flannel|default(False)|bool %} +          attach_data_net: true +          data_net:    { get_resource: data_net } +          data_subnet: { get_resource: data_subnet } +{% endif %} +{% endif %} +          secgrp: +{% if openshift_openstack_flat_secgrp|default(False)|bool %} +            - { get_resource: flat-secgrp } +{% else %} +            - { get_resource: master-secgrp } +            - { get_resource: node-secgrp } +{% if openshift_openstack_num_etcd|int == 0 %} +            - { get_resource: etcd-secgrp } +{% endif %} +{% endif %} +            - { get_resource: common-secgrp } +          floating_network: +            if: +              - no_floating +              - null +              - {{ openshift_openstack_external_network_name }} +{% if openshift_openstack_use_bastion|bool or openshift_openstack_provider_network_name %} +          attach_float_net: false +{% endif %} +          volume_size: {{ openshift_openstack_master_volume_size }} +{% if openshift_openstack_master_server_group_policies|length > 0 %} +          scheduler_hints: +            group: { get_resource: master_server_group } +{% endif %} +{% if not openshift_openstack_provider_network_name %} +    depends_on: +      - interface +{% endif %} + +  compute_nodes: +    type: OS::Heat::ResourceGroup +    properties: +      count: {{ openshift_openstack_num_nodes }} +      removal_policies: +      - resource_list: {{ openshift_openstack_nodes_to_remove }} +      resource_def: +        type: server.yaml +        properties: +          name: +            str_replace: +              template: sub_type_k8s_type-%index%.cluster_id +              params: +                cluster_id: {{ openshift_openstack_stack_name }} +                sub_type_k8s_type: {{ openshift_openstack_node_hostname }} +          cluster_env: {{ openshift_openstack_public_dns_domain }} +          cluster_id:  {{ openshift_openstack_stack_name }} +          group: +            str_replace: +              template: k8s_type.cluster_id +              params: +                k8s_type: nodes +                cluster_id: {{ openshift_openstack_stack_name }} +          type:        node +          subtype:     app +          node_labels: +{% for k, v in openshift_openstack_cluster_node_labels.app.iteritems() %} +            {{ k|e }}: {{ v|e }} +{% endfor %} +          image:       {{ openshift_openstack_node_image }} +          flavor:      {{ openshift_openstack_node_flavor }} +          key_name:    {{ openshift_openstack_keypair_name }} +{% if openshift_openstack_provider_network_name %} +          net:         {{ openshift_openstack_provider_network_name }} +          net_name:         {{ openshift_openstack_provider_network_name }} +{% else %} +          net:         { get_resource: net } +          subnet:      { get_resource: subnet } +          net_name: +            str_replace: +              template: openshift-ansible-cluster_id-net +              params: +                cluster_id: {{ openshift_openstack_stack_name }} +{% if openshift_use_flannel|default(False)|bool %} +          attach_data_net: true +          data_net:    { get_resource: data_net } +          data_subnet: { get_resource: data_subnet } +{% endif %} +{% endif %} +          secgrp: +            - { get_resource: {% if openshift_openstack_flat_secgrp|default(False)|bool %}flat-secgrp{% else %}node-secgrp{% endif %} } +            - { get_resource: common-secgrp } +          floating_network: +            if: +              - no_floating +              - null +              - {{ openshift_openstack_external_network_name }} +{% if openshift_openstack_use_bastion|bool or openshift_openstack_provider_network_name %} +          attach_float_net: false +{% endif %} +          volume_size: {{ openshift_openstack_node_volume_size }} +{% if not openshift_openstack_provider_network_name %} +    depends_on: +      - interface +{% endif %} + +  infra_nodes: +    type: OS::Heat::ResourceGroup +    properties: +      count: {{ openshift_openstack_num_infra }} +      resource_def: +        type: server.yaml +        properties: +          name: +            str_replace: +              template: sub_type_k8s_type-%index%.cluster_id +              params: +                cluster_id: {{ openshift_openstack_stack_name }} +                sub_type_k8s_type: {{ openshift_openstack_infra_hostname }} +          cluster_env: {{ openshift_openstack_public_dns_domain }} +          cluster_id:  {{ openshift_openstack_stack_name }} +          group: +            str_replace: +              template: k8s_type.cluster_id +              params: +                k8s_type: infra +                cluster_id: {{ openshift_openstack_stack_name }} +          type:        node +          subtype:     infra +          node_labels: +{% for k, v in openshift_openstack_cluster_node_labels.infra.iteritems() %} +            {{ k|e }}: {{ v|e }} +{% endfor %} +          image:       {{ openshift_openstack_infra_image }} +          flavor:      {{ openshift_openstack_infra_flavor }} +          key_name:    {{ openshift_openstack_keypair_name }} +{% if openshift_openstack_provider_network_name %} +          net:         {{ openshift_openstack_provider_network_name }} +          net_name:         {{ openshift_openstack_provider_network_name }} +{% else %} +          net:         { get_resource: net } +          subnet:      { get_resource: subnet } +          net_name: +            str_replace: +              template: openshift-ansible-cluster_id-net +              params: +                cluster_id: {{ openshift_openstack_stack_name }} +{% if openshift_use_flannel|default(False)|bool %} +          attach_data_net: true +          data_net:    { get_resource: data_net } +          data_subnet: { get_resource: data_subnet } +{% endif %} +{% endif %} +          secgrp: +# TODO(bogdando) filter only required node rules into infra-secgrp +{% if openshift_openstack_flat_secgrp|default(False)|bool %} +            - { get_resource: flat-secgrp } +{% else %} +            - { get_resource: node-secgrp } +{% endif %} +{% if openshift_openstack_ui_ssh_tunnel|bool and openshift_openstack_num_masters|int < 2 %} +            - { get_resource: lb-secgrp } +{% endif %} +            - { get_resource: infra-secgrp } +            - { get_resource: common-secgrp } +{% if not openshift_openstack_provider_network_name %} +          floating_network: {{ openshift_openstack_external_network_name }} +{% endif %} +          volume_size: {{ openshift_openstack_infra_volume_size }} +{% if openshift_openstack_infra_server_group_policies|length > 0 %} +          scheduler_hints: +            group: { get_resource: infra_server_group } +{% endif %} +{% if not openshift_openstack_provider_network_name %} +    depends_on: +      - interface +{% endif %} + +{% if openshift_openstack_num_dns|int > 0 %} +  dns: +    type: OS::Heat::ResourceGroup +    properties: +      count: {{ openshift_openstack_num_dns }} +      resource_def: +        type: server.yaml +        properties: +          name: +            str_replace: +              template: k8s_type-%index%.cluster_id +              params: +                cluster_id: {{ openshift_openstack_stack_name }} +                k8s_type: {{ openshift_openstack_dns_hostname }} +          cluster_env: {{ openshift_openstack_public_dns_domain }} +          cluster_id:  {{ openshift_openstack_stack_name }} +          group: +            str_replace: +              template: k8s_type.cluster_id +              params: +                k8s_type: dns +                cluster_id: {{ openshift_openstack_stack_name }} +          type:        dns +          image:       {{ openshift_openstack_dns_image }} +          flavor:      {{ openshift_openstack_dns_flavor }} +          key_name:    {{ openshift_openstack_keypair_name }} +{% if openshift_openstack_provider_network_name %} +          net:         {{ openshift_openstack_provider_network_name }} +          net_name:         {{ openshift_openstack_provider_network_name }} +{% else %} +          net:         { get_resource: net } +          subnet:      { get_resource: subnet } +          net_name: +            str_replace: +              template: openshift-ansible-cluster_id-net +              params: +                cluster_id: {{ openshift_openstack_stack_name }} +{% endif %} +          secgrp: +            - { get_resource: dns-secgrp } +            - { get_resource: common-secgrp } +{% if not openshift_openstack_provider_network_name %} +          floating_network: {{ openshift_openstack_external_network_name }} +{% endif %} +          volume_size: {{ openshift_openstack_dns_volume_size }} +{% if not openshift_openstack_provider_network_name %} +    depends_on: +      - interface +{% endif %} +{% endif %} diff --git a/roles/openshift_openstack/templates/heat_stack_server.yaml.j2 b/roles/openshift_openstack/templates/heat_stack_server.yaml.j2 new file mode 100644 index 000000000..a829da34f --- /dev/null +++ b/roles/openshift_openstack/templates/heat_stack_server.yaml.j2 @@ -0,0 +1,270 @@ +heat_template_version: 2016-10-14 + +description: OpenShift cluster server + +parameters: + +  name: +    type: string +    label: Name +    description: Name + +  group: +    type: string +    label: Host Group +    description: The Primary Ansible Host Group +    default: host + +  cluster_env: +    type: string +    label: Cluster environment +    description: Environment of the cluster + +  cluster_id: +    type: string +    label: Cluster ID +    description: Identifier of the cluster + +  type: +    type: string +    label: Type +    description: Type master or node + +  subtype: +    type: string +    label: Sub-type +    description: Sub-type compute or infra for nodes, default otherwise +    default: default + +  key_name: +    type: string +    label: Key name +    description: Key name of keypair + +  image: +    type: string +    label: Image +    description: Name of the image + +  flavor: +    type: string +    label: Flavor +    description: Name of the flavor + +  net: +    type: string +    label: Net ID +    description: Net resource + +  net_name: +    type: string +    label: Net name +    description: Net name + +{% if not openshift_openstack_provider_network_name %} +  subnet: +    type: string +    label: Subnet ID +    description: Subnet resource +{% endif %} + +{% if openshift_use_flannel|default(False)|bool %} +  attach_data_net: +    type: boolean +    default: false +    label: Attach-data-net +    description: A switch for data port connection + +  data_net: +    type: string +    default: '' +    label: Net ID +    description: Net resource + +{% if not openshift_openstack_provider_network_name %} +  data_subnet: +    type: string +    default: '' +    label: Subnet ID +    description: Subnet resource +{% endif %} +{% endif %} + +  secgrp: +    type: comma_delimited_list +    label: Security groups +    description: Security group resources + +  attach_float_net: +    type: boolean +    default: true + +    label: Attach-float-net +    description: A switch for floating network port connection + +{% if not openshift_openstack_provider_network_name %} +  floating_network: +    type: string +    default: '' +    label: Floating network +    description: Network to allocate floating IP from +{% endif %} + +  availability_zone: +    type: string +    description: The Availability Zone to launch the instance. +    default: nova + +  volume_size: +    type: number +    description: Size of the volume to be created. +    default: 1 +    constraints: +      - range: { min: 1, max: 1024 } +        description: must be between 1 and 1024 Gb. + +  node_labels: +    type: json +    description: OpenShift Node Labels +    default: {"region": "default" } + +  scheduler_hints: +    type: json +    description: Server scheduler hints. +    default: {} + +outputs: + +  name: +    description: Name of the server +    value: { get_attr: [ server, name ] } + +  private_ip: +    description: Private IP of the server +    value: +      get_attr: +        - server +        - addresses +        - { get_param: net_name } +        - 0 +        - addr + +  floating_ip: +    description: Floating IP of the server +    value: +      get_attr: +        - server +        - addresses +        - { get_param: net_name } +{% if openshift_openstack_provider_network_name %} +        - 0 +{% else %} +        - 1 +{% endif %} +        - addr + +conditions: +  no_floating: {not: { get_param: attach_float_net} } +{% if openshift_use_flannel|default(False)|bool %} +  no_data_subnet: {not: { get_param: attach_data_net} } +{% endif %} + +resources: + +  server: +    type: OS::Nova::Server +    properties: +      name:      { get_param: name } +      key_name:  { get_param: key_name } +      image:     { get_param: image } +      flavor:    { get_param: flavor } +      networks: +{% if openshift_use_flannel|default(False)|bool %} +        if: +          - no_data_subnet +{% if use_trunk_ports|default(false)|bool %} +          - - port:  { get_attr: [trunk-port, port_id] } +{% else %} +          - - port:  { get_resource: port } +{% endif %} +{% if use_trunk_ports|default(false)|bool %} +          - - port:  { get_attr: [trunk-port, port_id] } +{% else %} +          - - port:  { get_resource: port } +            - port:  { get_resource: data_port } +{% endif %} + +{% else %} +{% if use_trunk_ports|default(false)|bool %} +        - port:  { get_attr: [trunk-port, port_id] } +{% else %} +        - port:  { get_resource: port } +{% endif %} +{% endif %} +      user_data: +        get_file: user-data +      user_data_format: RAW +      user_data_update_policy: IGNORE +      metadata: +        group: { get_param: group } +        environment: { get_param: cluster_env } +        clusterid: { get_param: cluster_id } +        host-type: { get_param: type } +        sub-host-type:    { get_param: subtype } +        node_labels: { get_param: node_labels } +      scheduler_hints: { get_param: scheduler_hints } + +{% if use_trunk_ports|default(false)|bool %} +  trunk-port: +    type: OS::Neutron::Trunk +    properties: +      name: { get_param: name } +      port: { get_resource: port } +{% endif %} + +  port: +    type: OS::Neutron::Port +    properties: +      network: { get_param: net } +{% if not openshift_openstack_provider_network_name %} +      fixed_ips: +        - subnet: { get_param: subnet } +{% endif %} +      security_groups: { get_param: secgrp } + +{% if openshift_use_flannel|default(False)|bool %} +  data_port: +    type: OS::Neutron::Port +    condition: { not: no_data_subnet } +    properties: +      network: { get_param: data_net } +      port_security_enabled: false +{% if not openshift_openstack_provider_network_name %} +      fixed_ips: +        - subnet: { get_param: data_subnet } +{% endif %} +{% endif %} + +{% if not openshift_openstack_provider_network_name %} +  floating-ip: +    condition: { not: no_floating } +    type: OS::Neutron::FloatingIP +    properties: +      floating_network: { get_param: floating_network } +      port_id: { get_resource: port } +{% endif %} + +{% if not openshift_openstack_ephemeral_volumes|default(false)|bool %} +  cinder_volume: +    type: OS::Cinder::Volume +    properties: +      size: { get_param: volume_size } +      availability_zone: { get_param: availability_zone } + +  volume_attachment: +    type: OS::Cinder::VolumeAttachment +    properties: +      volume_id: { get_resource: cinder_volume } +      instance_uuid: { get_resource: server } +      mountpoint: /dev/sdb +{% endif %} diff --git a/roles/openshift_openstack/templates/user_data.j2 b/roles/openshift_openstack/templates/user_data.j2 new file mode 100644 index 000000000..eb65f7cec --- /dev/null +++ b/roles/openshift_openstack/templates/user_data.j2 @@ -0,0 +1,13 @@ +#cloud-config +disable_root: true + +system_info: +  default_user: +    name: openshift +    sudo: ["ALL=(ALL) NOPASSWD: ALL"] + +write_files: +  - path: /etc/sudoers.d/00-openshift-no-requiretty +    permissions: 440 +    content: | +      Defaults:openshift !requiretty | 
