diff options
Diffstat (limited to 'roles')
38 files changed, 465 insertions, 105 deletions
| diff --git a/roles/etcd/defaults/main.yaml b/roles/etcd/defaults/main.yaml index e6b10cab7..a2212bacd 100644 --- a/roles/etcd/defaults/main.yaml +++ b/roles/etcd/defaults/main.yaml @@ -1,6 +1,5 @@  --- -etcd_service: "{{ 'etcd' if not openshift.common.is_containerized | bool else 'etcd_container' }}" -etcd_interface: "{{ ansible_default_ipv4.interface }}" +etcd_service: "{{ 'etcd' if not etcd_is_containerized | bool else 'etcd_container' }}"  etcd_client_port: 2379  etcd_peer_port: 2380  etcd_url_scheme: http @@ -9,10 +8,10 @@ etcd_peer_url_scheme: http  etcd_initial_cluster_state: new  etcd_initial_cluster_token: etcd-cluster-1 -etcd_initial_advertise_peer_urls: "{{ etcd_peer_url_scheme }}://{{ hostvars[inventory_hostname]['ansible_' + etcd_interface]['ipv4']['address'] }}:{{ etcd_peer_port }}" -etcd_listen_peer_urls: "{{ etcd_peer_url_scheme }}://{{ hostvars[inventory_hostname]['ansible_' + etcd_interface]['ipv4']['address'] }}:{{ etcd_peer_port }}" -etcd_advertise_client_urls: "{{ etcd_url_scheme }}://{{ hostvars[inventory_hostname]['ansible_' + etcd_interface]['ipv4']['address'] }}:{{ etcd_client_port }}" -etcd_listen_client_urls: "{{ etcd_url_scheme }}://{{ hostvars[inventory_hostname]['ansible_' + etcd_interface]['ipv4']['address'] }}:{{ etcd_client_port }}" +etcd_initial_advertise_peer_urls: "{{ etcd_peer_url_scheme }}://{{ etcd_ip }}:{{ etcd_peer_port }}" +etcd_listen_peer_urls: "{{ etcd_peer_url_scheme }}://{{ etcd_ip }}:{{ etcd_peer_port }}" +etcd_advertise_client_urls: "{{ etcd_url_scheme }}://{{ etcd_ip }}:{{ etcd_client_port }}" +etcd_listen_client_urls: "{{ etcd_url_scheme }}://{{ etcd_ip }}:{{ etcd_client_port }}"  etcd_data_dir: /var/lib/etcd/ diff --git a/roles/etcd/meta/main.yml b/roles/etcd/meta/main.yml index 36906b347..a71b36237 100644 --- a/roles/etcd/meta/main.yml +++ b/roles/etcd/meta/main.yml @@ -16,6 +16,5 @@ galaxy_info:    - cloud    - system  dependencies: -- { role: openshift_docker }  - { role: os_firewall }  - { role: etcd_common } diff --git a/roles/etcd/tasks/main.yml b/roles/etcd/tasks/main.yml index afec6b30b..a798dc973 100644 --- a/roles/etcd/tasks/main.yml +++ b/roles/etcd/tasks/main.yml @@ -1,36 +1,35 @@  --- -- fail: -    msg: Interface {{ etcd_interface }} not found -  when: "'ansible_' ~ etcd_interface not in hostvars[inventory_hostname]" - -- fail: -    msg: IPv4 address not found for {{ etcd_interface }} -  when: "'ipv4' not in hostvars[inventory_hostname]['ansible_' ~ etcd_interface] or 'address' not in hostvars[inventory_hostname]['ansible_' ~ etcd_interface].ipv4" +- name: Set hostname and ip facts +  set_fact: +    # Store etcd_hostname and etcd_ip such that they will be available +    # in hostvars. Defaults for these variables are set in etcd_common. +    etcd_hostname: "{{ etcd_hostname }}" +    etcd_ip: "{{ etcd_ip }}"  - name: Install etcd    action: "{{ ansible_pkg_mgr }} name=etcd state=present" -  when: not openshift.common.is_containerized | bool +  when: not etcd_is_containerized | bool  - name: Pull etcd container    command: docker pull {{ openshift.etcd.etcd_image }} -  when: openshift.common.is_containerized | bool +  when: etcd_is_containerized | bool  - name: Install etcd container service file    template:      dest: "/etc/systemd/system/etcd_container.service"      src: etcd.docker.service    register: install_etcd_result -  when: openshift.common.is_containerized | bool +  when: etcd_is_containerized | bool  - name: Ensure etcd datadir exists -  when: openshift.common.is_containerized | bool +  when: etcd_is_containerized | bool    file:      path: "{{ etcd_data_dir }}"      state: directory      mode: 0700  - name: Disable system etcd when containerized -  when: openshift.common.is_containerized | bool +  when: etcd_is_containerized | bool    service:      name: etcd      state: stopped @@ -42,27 +41,27 @@    changed_when: false  - name: Mask system etcd when containerized -  when: openshift.common.is_containerized | bool and 'LoadState=not-found' not in etcd_show.stdout +  when: etcd_is_containerized | bool and 'LoadState=not-found' not in etcd_show.stdout    command: systemctl mask etcd  - name: Reload systemd units    command: systemctl daemon-reload -  when: openshift.common.is_containerized | bool and ( install_etcd_result | changed ) +  when: etcd_is_containerized | bool and ( install_etcd_result | changed )  - name: Validate permissions on the config dir    file:      path: "{{ etcd_conf_dir }}"      state: directory -    owner: "{{ 'etcd' if not openshift.common.is_containerized | bool else omit }}" -    group: "{{ 'etcd' if not openshift.common.is_containerized | bool else omit }}" +    owner: "{{ 'etcd' if not etcd_is_containerized | bool else omit }}" +    group: "{{ 'etcd' if not etcd_is_containerized | bool else omit }}"      mode: 0700  - name: Validate permissions on certificate files    file:      path: "{{ item }}"      mode: 0600 -    owner: "{{ 'etcd' if not openshift.common.is_containerized | bool else omit }}" -    group: "{{ 'etcd' if not openshift.common.is_containerized | bool else omit }}" +    owner: "{{ 'etcd' if not etcd_is_containerized | bool else omit }}" +    group: "{{ 'etcd' if not etcd_is_containerized | bool else omit }}"    when: etcd_url_scheme == 'https'    with_items:    - "{{ etcd_ca_file }}" @@ -73,8 +72,8 @@    file:      path: "{{ item }}"      mode: 0600 -    owner: "{{ 'etcd' if not openshift.common.is_containerized | bool else omit }}" -    group: "{{ 'etcd' if not openshift.common.is_containerized | bool else omit }}" +    owner: "{{ 'etcd' if not etcd_is_containerized | bool else omit }}" +    group: "{{ 'etcd' if not etcd_is_containerized | bool else omit }}"    when: etcd_peer_url_scheme == 'https'    with_items:    - "{{ etcd_peer_ca_file }}" diff --git a/roles/etcd/templates/etcd.conf.j2 b/roles/etcd/templates/etcd.conf.j2 index 28816fd87..cd048ec60 100644 --- a/roles/etcd/templates/etcd.conf.j2 +++ b/roles/etcd/templates/etcd.conf.j2 @@ -1,15 +1,15 @@  {% macro initial_cluster() -%} -{% for host in groups[etcd_peers_group] -%} +{% for host in etcd_peers -%}  {% if loop.last -%} -{{ host }}={{ etcd_peer_url_scheme }}://{{ etcd_host_int_map[host].interface.ipv4.address }}:{{ etcd_peer_port }} +{{ hostvars[host].etcd_hostname }}={{ etcd_peer_url_scheme }}://{{ hostvars[host].etcd_ip }}:{{ etcd_peer_port }}  {%- else -%} -{{ host }}={{ etcd_peer_url_scheme }}://{{ etcd_host_int_map[host].interface.ipv4.address }}:{{ etcd_peer_port }}, +{{ hostvars[host].etcd_hostname }}={{ etcd_peer_url_scheme }}://{{ hostvars[host].etcd_ip }}:{{ etcd_peer_port }},  {%- endif -%}  {% endfor -%}  {% endmacro -%} -{% if groups[etcd_peers_group] and groups[etcd_peers_group] | length > 1 %} -ETCD_NAME={{ inventory_hostname }} +{% if etcd_peers | default([]) | length > 1 %} +ETCD_NAME={{ etcd_hostname }}  ETCD_LISTEN_PEER_URLS={{ etcd_listen_peer_urls }}  {% else %}  ETCD_NAME=default @@ -23,7 +23,7 @@ ETCD_LISTEN_CLIENT_URLS={{ etcd_listen_client_urls }}  #ETCD_MAX_WALS=5  #ETCD_CORS= -{% if groups[etcd_peers_group] and groups[etcd_peers_group] | length > 1 %} +{% if etcd_peers | default([]) | length > 1 %}  #[cluster]  ETCD_INITIAL_ADVERTISE_PEER_URLS={{ etcd_initial_advertise_peer_urls }}  ETCD_INITIAL_CLUSTER={{ initial_cluster() }} diff --git a/roles/etcd_ca/tasks/main.yml b/roles/etcd_ca/tasks/main.yml index cf7bc00a3..e1bb9baed 100644 --- a/roles/etcd_ca/tasks/main.yml +++ b/roles/etcd_ca/tasks/main.yml @@ -1,7 +1,7 @@  ---  - name: Install openssl    action: "{{ ansible_pkg_mgr }} name=openssl state=present" -  when: not openshift.common.is_atomic | bool +  when: not etcd_is_atomic | bool  - file:      path: "{{ item }}" diff --git a/roles/etcd_certificates/tasks/client.yml b/roles/etcd_certificates/tasks/client.yml index 6aa4883e0..7bf95809f 100644 --- a/roles/etcd_certificates/tasks/client.yml +++ b/roles/etcd_certificates/tasks/client.yml @@ -12,13 +12,13 @@      -config {{ etcd_openssl_conf }}      -out {{ item.etcd_cert_prefix }}client.csr      -reqexts {{ etcd_req_ext }} -batch -nodes -    -subj /CN={{ item.openshift.common.hostname }} +    -subj /CN={{ item.etcd_hostname }}    args:      chdir: "{{ etcd_generated_certs_dir }}/{{ item.etcd_cert_subdir }}"      creates: "{{ etcd_generated_certs_dir ~ '/' ~  item.etcd_cert_subdir ~ '/'                   ~ item.etcd_cert_prefix ~ 'client.csr' }}"    environment: -    SAN: "IP:{{ item.openshift.common.ip }}" +    SAN: "IP:{{ item.etcd_ip }}"    with_items: etcd_needing_client_certs  - name: Sign and create the client crt @@ -32,7 +32,7 @@      creates: "{{ etcd_generated_certs_dir ~ '/' ~  item.etcd_cert_subdir ~ '/'                   ~ item.etcd_cert_prefix ~ 'client.crt' }}"    environment: -    SAN: "IP:{{ item.openshift.common.ip }}" +    SAN: "IP:{{ item.etcd_ip }}"    with_items: etcd_needing_client_certs  - file: diff --git a/roles/etcd_certificates/tasks/server.yml b/roles/etcd_certificates/tasks/server.yml index 3499dcbef..2589c5192 100644 --- a/roles/etcd_certificates/tasks/server.yml +++ b/roles/etcd_certificates/tasks/server.yml @@ -12,13 +12,13 @@      -config {{ etcd_openssl_conf }}      -out {{ item.etcd_cert_prefix }}server.csr      -reqexts {{ etcd_req_ext }} -batch -nodes -    -subj /CN={{ item.openshift.common.hostname }} +    -subj /CN={{ item.etcd_hostname }}    args:      chdir: "{{ etcd_generated_certs_dir }}/{{ item.etcd_cert_subdir }}"      creates: "{{ etcd_generated_certs_dir ~ '/' ~  item.etcd_cert_subdir ~ '/'                   ~ item.etcd_cert_prefix ~ 'server.csr' }}"    environment: -    SAN: "IP:{{ etcd_host_int_map[item.inventory_hostname].interface.ipv4.address }}" +    SAN: "IP:{{ item.etcd_ip }}"    with_items: etcd_needing_server_certs  - name: Sign and create the server crt @@ -32,7 +32,7 @@      creates: "{{ etcd_generated_certs_dir ~ '/' ~  item.etcd_cert_subdir ~ '/'                   ~ item.etcd_cert_prefix ~ 'server.crt' }}"    environment: -    SAN: "IP:{{ etcd_host_int_map[item.inventory_hostname].interface.ipv4.address }}" +    SAN: "IP:{{ item.etcd_ip }}"    with_items: etcd_needing_server_certs  - name: Create the peer csr @@ -41,13 +41,13 @@      -config {{ etcd_openssl_conf }}      -out {{ item.etcd_cert_prefix }}peer.csr      -reqexts {{ etcd_req_ext }} -batch -nodes -    -subj /CN={{ item.openshift.common.hostname }} +    -subj /CN={{ item.etcd_hostname }}    args:      chdir: "{{ etcd_generated_certs_dir }}/{{ item.etcd_cert_subdir }}"      creates: "{{ etcd_generated_certs_dir ~ '/' ~  item.etcd_cert_subdir ~ '/'                   ~ item.etcd_cert_prefix ~ 'peer.csr' }}"    environment: -    SAN: "IP:{{ etcd_host_int_map[item.inventory_hostname].interface.ipv4.address }}" +    SAN: "IP:{{ item.etcd_ip }}"    with_items: etcd_needing_server_certs  - name: Sign and create the peer crt @@ -61,7 +61,7 @@      creates: "{{ etcd_generated_certs_dir ~ '/' ~  item.etcd_cert_subdir ~ '/'                   ~ item.etcd_cert_prefix ~ 'peer.crt' }}"    environment: -    SAN: "IP:{{ etcd_host_int_map[item.inventory_hostname].interface.ipv4.address }}" +    SAN: "IP:{{ item.etcd_ip }}"    with_items: etcd_needing_server_certs  - file: diff --git a/roles/etcd_common/defaults/main.yml b/roles/etcd_common/defaults/main.yml index 3af509448..1ff1d6ef8 100644 --- a/roles/etcd_common/defaults/main.yml +++ b/roles/etcd_common/defaults/main.yml @@ -1,6 +1,4 @@  --- -etcd_peers_group: oo_etcd_to_config -  # etcd server vars  etcd_conf_dir: /etc/etcd  etcd_ca_file: "{{ etcd_conf_dir }}/ca.crt" @@ -28,3 +26,9 @@ etcd_ca_db: "{{ etcd_ca_dir }}/index.txt"  etcd_ca_serial: "{{ etcd_ca_dir }}/serial"  etcd_ca_crl_number: "{{ etcd_ca_dir }}/crlnumber"  etcd_ca_default_days: 365 + +# etcd server & certificate vars +etcd_hostname: "{{ inventory_hostname }}" +etcd_ip: "{{ ansible_default_ipv4.address }}" +etcd_is_atomic: False +etcd_is_containerized: False diff --git a/roles/etcd_common/tasks/main.yml b/roles/etcd_common/tasks/main.yml deleted file mode 100644 index be75fdab2..000000000 --- a/roles/etcd_common/tasks/main.yml +++ /dev/null @@ -1,13 +0,0 @@ ---- -- set_fact: -    etcd_host_int_map: "{{ lookup('template', '../templates/host_int_map.j2') | from_yaml }}" - -- fail: -    msg: "Interface {{ item.value.etcd_interface }} not found on host {{ item.key }}" -  when: "'etcd_interface' in item.value and 'interface' not in item.value" -  with_dict: etcd_host_int_map | default({}) - -- fail: -    msg: IPv4 address not found for {{ item.value.interface.device }} on host {{ item.key }} -  when: "'ipv4' not in item.value.interface or 'address' not in item.value.interface.ipv4" -  with_dict: etcd_host_int_map | default({}) diff --git a/roles/etcd_common/templates/host_int_map.j2 b/roles/etcd_common/templates/host_int_map.j2 deleted file mode 100644 index 9c9c76413..000000000 --- a/roles/etcd_common/templates/host_int_map.j2 +++ /dev/null @@ -1,13 +0,0 @@ ---- -{% for host in groups[etcd_peers_group] %} -{% set entry=hostvars[host] %} -{{ entry.inventory_hostname }}: -{% if 'etcd_interface' in entry %} -  etcd_interface: {{ entry.etcd_interface }} -{% if entry.etcd_interface in entry.ansible_interfaces %} -  interface: {{ entry['ansible_' ~ entry.etcd_interface] | to_json }} -{% endif %} -{% else %} -  interface: {{ entry['ansible_' ~ entry.ansible_default_ipv4.interface] | to_json }} -{% endif %} -{% endfor %} diff --git a/roles/flannel_register/README.md b/roles/flannel_register/README.md index ba7541ab1..623c4c7cf 100644 --- a/roles/flannel_register/README.md +++ b/roles/flannel_register/README.md @@ -14,7 +14,7 @@ Role Variables  | Name                | Default value                                      | Description                                     |  |---------------------|----------------------------------------------------|-------------------------------------------------| -| flannel_network     | {{ openshift.master.portal_net }} or 172.16.1.1/16 | interface to use for inter-host communication   | +| flannel_network     | {{ openshift.common.portal_net }} or 172.16.1.1/16 | interface to use for inter-host communication   |  | flannel_min_network | {{ min_network }} or 172.16.5.0                    | beginning of IP range for the subnet allocation |  | flannel_subnet_len  | /openshift.com/network                             | size of the subnet allocated to each host       |  | flannel_etcd_key    | /openshift.com/network                             | etcd prefix                                     | diff --git a/roles/flannel_register/defaults/main.yaml b/roles/flannel_register/defaults/main.yaml index 269d1a17c..b1279aa88 100644 --- a/roles/flannel_register/defaults/main.yaml +++ b/roles/flannel_register/defaults/main.yaml @@ -1,5 +1,5 @@  --- -flannel_network: "{{ openshift.master.portal_net | default('172.30.0.0/16', true) }}" +flannel_network: "{{ openshift.common.portal_net | default('172.30.0.0/16', true) }}"  flannel_min_network: 172.30.5.0  flannel_subnet_len: 24  flannel_etcd_key: /openshift.com/network diff --git a/roles/openshift_common/README.md b/roles/openshift_common/README.md index 87306d4a6..2a271854b 100644 --- a/roles/openshift_common/README.md +++ b/roles/openshift_common/README.md @@ -20,6 +20,7 @@ Role Variables  | openshift_ip              | UNDEF             | Internal IP address to use for this host    |  | openshift_public_hostname | UNDEF             | Public hostname to use for this host        |  | openshift_public_ip       | UNDEF             | Public IP address to use for this host      | +| openshift_portal_net      | UNDEF             | Service IP CIDR |  Dependencies  ------------ diff --git a/roles/openshift_common/tasks/main.yml b/roles/openshift_common/tasks/main.yml index eda43b9f8..d5166b52e 100644 --- a/roles/openshift_common/tasks/main.yml +++ b/roles/openshift_common/tasks/main.yml @@ -27,6 +27,8 @@        use_nuage: "{{ openshift_use_nuage | default(None) }}"        use_manageiq: "{{ openshift_use_manageiq | default(None) }}"        data_dir: "{{ openshift_data_dir | default(None) }}" +      portal_net: "{{ openshift_portal_net | default(openshift_master_portal_net) | default(None) }}" +      use_dnsmasq: "{{ openshift_use_dnsmasq | default(None) }}"  # Using oo_image_tag_to_rpm_version here is a workaround for how  # openshift_version is set.  That value is computed based on either RPM diff --git a/roles/openshift_etcd/meta/main.yml b/roles/openshift_etcd/meta/main.yml index 5e5f96d44..7cc548f69 100644 --- a/roles/openshift_etcd/meta/main.yml +++ b/roles/openshift_etcd/meta/main.yml @@ -12,7 +12,7 @@ galaxy_info:    categories:    - cloud  dependencies: -- role: openshift_facts +- role: openshift_etcd_facts  - role: openshift_docker    when: openshift.common.is_containerized | bool  - role: etcd diff --git a/roles/openshift_etcd_certificates/meta/main.yml b/roles/openshift_etcd_certificates/meta/main.yml new file mode 100644 index 000000000..2725fdb51 --- /dev/null +++ b/roles/openshift_etcd_certificates/meta/main.yml @@ -0,0 +1,16 @@ +--- +galaxy_info: +  author: Andrew Butcher +  description: OpenShift etcd Certificates +  company: Red Hat, Inc. +  license: Apache License, Version 2.0 +  min_ansible_version: 1.9 +  platforms: +  - name: EL +    versions: +    - 7 +  categories: +  - cloud +dependencies: +- role: openshift_etcd_facts +- role: etcd_certificates diff --git a/roles/openshift_etcd_facts/meta/main.yml b/roles/openshift_etcd_facts/meta/main.yml new file mode 100644 index 000000000..18d289ea1 --- /dev/null +++ b/roles/openshift_etcd_facts/meta/main.yml @@ -0,0 +1,15 @@ +--- +galaxy_info: +  author: Andrew Butcher +  description: OpenShift etcd Facts +  company: Red Hat, Inc. +  license: Apache License, Version 2.0 +  min_ansible_version: 1.9 +  platforms: +  - name: EL +    versions: +    - 7 +  categories: +  - cloud +dependencies: +- role: openshift_common diff --git a/roles/openshift_etcd_facts/vars/main.yml b/roles/openshift_etcd_facts/vars/main.yml new file mode 100644 index 000000000..6f3894565 --- /dev/null +++ b/roles/openshift_etcd_facts/vars/main.yml @@ -0,0 +1,5 @@ +--- +etcd_is_containerized: "{{ openshift.common.is_containerized }}" +etcd_is_atomic: "{{ openshift.common.is_atomic }}" +etcd_hostname: "{{ openshift.common.hostname }}" +etcd_ip: "{{ openshift.common.ip }}" diff --git a/roles/openshift_facts/library/openshift_facts.py b/roles/openshift_facts/library/openshift_facts.py index 9218e12ae..48b117b8f 100755 --- a/roles/openshift_facts/library/openshift_facts.py +++ b/roles/openshift_facts/library/openshift_facts.py @@ -56,12 +56,54 @@ def migrate_docker_facts(facts):      if 'node' in facts and 'portal_net' in facts['node']:          facts['docker']['hosted_registry_insecure'] = True          facts['docker']['hosted_registry_network'] = facts['node'].pop('portal_net') + +    # log_options was originally meant to be a comma separated string, but +    # we now prefer an actual list, with backward compatability: +    if 'log_options' in facts['docker'] and \ +            isinstance(facts['docker']['log_options'], basestring): +        facts['docker']['log_options'] = facts['docker']['log_options'].split(",") + +    return facts + +# TODO: We should add a generic migration function that takes source and destination +# paths and does the right thing rather than one function for common, one for node, etc. +def migrate_common_facts(facts): +    """ Migrate facts from various roles into common """ +    params = { +        'node': ('portal_net'), +        'master': ('portal_net') +    } +    if 'common' not in facts: +        facts['common'] = {} +    for role in params.keys(): +        if role in facts: +            for param in params[role]: +                if param in facts[role]: +                    facts['common'][param] = facts[role].pop(param) +    return facts + +def migrate_node_facts(facts): +    """ Migrate facts from various roles into node """ +    params = { +        'common': ('dns_ip'), +    } +    if 'node' not in facts: +        facts['node'] = {} +    for role in params.keys(): +        if role in facts: +            for param in params[role]: +                if param in facts[role]: +                    facts['node'][param] = facts[role].pop(param)      return facts  def migrate_local_facts(facts):      """ Apply migrations of local facts """      migrated_facts = copy.deepcopy(facts) -    return migrate_docker_facts(migrated_facts) +    migrated_facts = migrate_docker_facts(migrated_facts) +    migrated_facts = migrate_common_facts(migrated_facts) +    migrated_facts = migrate_node_facts(migrated_facts) +    migrated_facts = migrate_hosted_facts(migrated_facts) +    return migrated_facts  def migrate_hosted_facts(facts):      """ Apply migrations for master facts """ @@ -448,6 +490,27 @@ def set_metrics_facts_if_unset(facts):              facts['common']['use_cluster_metrics'] = use_cluster_metrics      return facts +def set_dnsmasq_facts_if_unset(facts): +    """ Set dnsmasq facts if not already present in facts +    Args: +        facts (dict) existing facts +    Returns: +        facts (dict) updated facts with values set if not previously set +    """ + +    if 'common' in facts: +        if 'use_dnsmasq' not in facts['common'] and facts['common']['version_gte_3_2_or_1_2']: +            facts['common']['use_dnsmasq'] = True +        else: +            facts['common']['use_dnsmasq'] = False +        if 'master' in facts and 'dns_port' not in facts['master']: +            if facts['common']['use_dnsmasq']: +                facts['master']['dns_port'] = 8053 +            else: +                facts['master']['dns_port'] = 53 + +    return facts +  def set_project_cfg_facts_if_unset(facts):      """ Set Project Configuration facts if not already present in facts dict              dict: @@ -586,11 +649,13 @@ def set_aggregate_facts(facts):      """      all_hostnames = set()      internal_hostnames = set() +    kube_svc_ip = first_ip(facts['common']['portal_net'])      if 'common' in facts:          all_hostnames.add(facts['common']['hostname'])          all_hostnames.add(facts['common']['public_hostname'])          all_hostnames.add(facts['common']['ip'])          all_hostnames.add(facts['common']['public_ip']) +        facts['common']['kube_svc_ip'] = kube_svc_ip          internal_hostnames.add(facts['common']['hostname'])          internal_hostnames.add(facts['common']['ip']) @@ -607,9 +672,8 @@ def set_aggregate_facts(facts):                           'kubernetes.default.svc', 'kubernetes.default.svc.' + cluster_domain]              all_hostnames.update(svc_names)              internal_hostnames.update(svc_names) -            first_svc_ip = first_ip(facts['master']['portal_net']) -            all_hostnames.add(first_svc_ip) -            internal_hostnames.add(first_svc_ip) +            all_hostnames.add(kube_svc_ip) +            internal_hostnames.add(kube_svc_ip)          facts['common']['all_hostnames'] = list(all_hostnames)          facts['common']['internal_hostnames'] = list(internal_hostnames) @@ -1154,7 +1218,7 @@ def merge_facts(orig, new, additive_facts_to_overwrite, protected_facts_to_overw              if key in inventory_json_facts:                  # Watchout for JSON facts that sometimes load as strings.                  # (can happen if the JSON contains a boolean) -                if isinstance(new[key], str): +                if isinstance(new[key], basestring):                      facts[key] = yaml.safe_load(new[key])                  else:                      facts[key] = copy.deepcopy(new[key]) @@ -1490,6 +1554,7 @@ class OpenShiftFacts(object):          facts = build_controller_args(facts)          facts = build_api_server_args(facts)          facts = set_version_facts_if_unset(facts) +        facts = set_dnsmasq_facts_if_unset(facts)          facts = set_manageiq_facts_if_unset(facts)          facts = set_aggregate_facts(facts)          facts = set_etcd_facts_if_unset(facts) @@ -1519,6 +1584,7 @@ class OpenShiftFacts(object):                                    deployment_type=deployment_type,                                    hostname=hostname,                                    public_hostname=hostname, +                                  portal_net='172.30.0.0/16',                                    client_binary='oc', admin_binary='oadm',                                    dns_domain='cluster.local',                                    install_examples=True, @@ -1546,7 +1612,7 @@ class OpenShiftFacts(object):                                        etcd_hosts='', etcd_port='4001',                                        portal_net='172.30.0.0/16',                                        embedded_etcd=True, embedded_kube=True, -                                      embedded_dns=True, dns_port='53', +                                      embedded_dns=True,                                        bind_addr='0.0.0.0',                                        session_max_seconds=3600,                                        session_name='ssn', @@ -1576,6 +1642,22 @@ class OpenShiftFacts(object):          if 'hosted' in roles or self.role == 'hosted':              defaults['hosted'] = dict( +                metrics=dict( +                    deploy=False, +                    storage=dict( +                        kind=None, +                        volume=dict( +                            name='metrics', +                            size='10Gi' +                        ), +                        nfs=dict( +                            directory='/exports', +                            options='*(rw,root_squash)'), +                        host=None, +                        access_modes=['ReadWriteMany'], +                        create_pv=True +                    ) +                ),                  registry=dict(                      storage=dict(                          kind=None, @@ -1777,15 +1859,12 @@ class OpenShiftFacts(object):                      if isinstance(val, basestring):                          val = [x.strip() for x in val.split(',')]                      new_local_facts['docker'][key] = list(set(val) - set([''])) +            # Convert legacy log_options comma sep string to a list if present: +            if 'log_options' in new_local_facts['docker'] and \ +                    isinstance(new_local_facts['docker']['log_options'], basestring): +                new_local_facts['docker']['log_options'] = new_local_facts['docker']['log_options'].split(',') -        for facts in new_local_facts.values(): -            keys_to_delete = [] -            if isinstance(facts, dict): -                for fact, value in facts.iteritems(): -                    if value == "" or value is None: -                        keys_to_delete.append(fact) -                for key in keys_to_delete: -                    del facts[key] +        new_local_facts = self.remove_empty_facts(new_local_facts)          if new_local_facts != local_facts:              self.validate_local_facts(new_local_facts) @@ -1796,6 +1875,23 @@ class OpenShiftFacts(object):          self.changed = changed          return new_local_facts +    def remove_empty_facts(self, facts=None): +        """ Remove empty facts + +            Args: +                facts (dict): facts to clean +        """ +        facts_to_remove = [] +        for fact, value in facts.iteritems(): +            if isinstance(facts[fact], dict): +                facts[fact] = self.remove_empty_facts(facts[fact]) +            else: +                if value == "" or value == [""] or value is None: +                    facts_to_remove.append(fact) +        for fact in facts_to_remove: +            del facts[fact] +        return facts +      def validate_local_facts(self, facts=None):          """ Validate local facts diff --git a/roles/openshift_hosted/tasks/router.yml b/roles/openshift_hosted/tasks/router.yml index 6a36f74b2..4ccbf4430 100644 --- a/roles/openshift_hosted/tasks/router.yml +++ b/roles/openshift_hosted/tasks/router.yml @@ -32,6 +32,7 @@      {{ openshift.common.client_binary }} --api-version='v1' -o json      get nodes -n default --config={{ openshift.common.config_base }}/master/admin.kubeconfig    register: openshift_hosted_router_nodes_json +  changed_when: false    when: openshift.hosted.router.replicas | default(None) == None  - name: Collect nodes matching router selector diff --git a/roles/openshift_master/defaults/main.yml b/roles/openshift_master/defaults/main.yml index 6bf28ff2b..09bde6002 100644 --- a/roles/openshift_master/defaults/main.yml +++ b/roles/openshift_master/defaults/main.yml @@ -9,10 +9,10 @@ os_firewall_allow:    port: "{{ openshift.master.api_port }}/tcp"  - service: api controllers https    port: "{{ openshift.master.controllers_port }}/tcp" -- service: dns tcp -  port: 53/tcp -- service: dns udp -  port: 53/udp +- service: skydns tcp +  port: "{{ openshift.master.dns_port }}/tcp" +- service: skydns udp +  port: "{{ openshift.master.dns_port }}/udp"  - service: Fluentd td-agent tcp    port: 24224/tcp  - service: Fluentd td-agent udp diff --git a/roles/openshift_master/templates/master.yaml.v1.j2 b/roles/openshift_master/templates/master.yaml.v1.j2 index 1009aa318..979b428bf 100644 --- a/roles/openshift_master/templates/master.yaml.v1.j2 +++ b/roles/openshift_master/templates/master.yaml.v1.j2 @@ -123,7 +123,7 @@ kubernetesMasterConfig:      keyFile: master.proxy-client.key    schedulerConfigFile: {{ openshift_master_scheduler_conf }}    servicesNodePortRange: "" -  servicesSubnet: {{ openshift.master.portal_net }} +  servicesSubnet: {{ openshift.common.portal_net }}    staticNodeNames: {{ openshift_node_ips | default([], true) }}  {% endif %}  masterClients: @@ -138,7 +138,7 @@ networkConfig:    networkPluginName: {{ openshift.common.sdn_network_plugin_name }}  {% endif %}  # serviceNetworkCIDR must match kubernetesMasterConfig.servicesSubnet -  serviceNetworkCIDR: {{ openshift.master.portal_net }} +  serviceNetworkCIDR: {{ openshift.common.portal_net }}  oauthConfig:  {% if 'oauth_always_show_provider_selection' in openshift.master %}    alwaysShowProviderSelection: {{ openshift.master.oauth_always_show_provider_selection }} diff --git a/roles/openshift_master_facts/tasks/main.yml b/roles/openshift_master_facts/tasks/main.yml index 4d7c04065..a020fdb41 100644 --- a/roles/openshift_master_facts/tasks/main.yml +++ b/roles/openshift_master_facts/tasks/main.yml @@ -30,10 +30,10 @@        embedded_etcd: "{{ openshift_master_embedded_etcd | default(None) }}"        embedded_kube: "{{ openshift_master_embedded_kube | default(None) }}"        embedded_dns: "{{ openshift_master_embedded_dns | default(None) }}" +      # defaults to 8053 when using dnsmasq in 1.2/3.2        dns_port: "{{ openshift_master_dns_port | default(None) }}"        bind_addr: "{{ openshift_master_bind_addr | default(None) }}"        pod_eviction_timeout: "{{ openshift_master_pod_eviction_timeout | default(None) }}" -      portal_net: "{{ openshift_master_portal_net | default(None) }}"        session_max_seconds: "{{ openshift_master_session_max_seconds | default(None) }}"        session_name: "{{ openshift_master_session_name | default(None) }}"        session_secrets_file: "{{ openshift_master_session_secrets_file | default(None) }}" @@ -54,7 +54,6 @@        mcs_allocator_range: "{{ osm_mcs_allocator_range | default(None) }}"        mcs_labels_per_project: "{{ osm_mcs_labels_per_project | default(None) }}"        uid_allocator_range: "{{ osm_uid_allocator_range | default(None) }}" -      router_selector: "{{ openshift_router_selector | default(None) }}"        registry_selector: "{{ openshift_registry_selector | default(None) }}"        api_server_args: "{{ osm_api_server_args | default(None) }}"        controller_args: "{{ osm_controller_args | default(None) }}" diff --git a/roles/openshift_metrics/README.md b/roles/openshift_metrics/README.md new file mode 100644 index 000000000..610917d7d --- /dev/null +++ b/roles/openshift_metrics/README.md @@ -0,0 +1,51 @@ +OpenShift Metrics with Hawkular +==================== + +OpenShift Metrics Installation + +Requirements +------------ +It requires subdomain fqdn to be set. +If persistence is enabled, then it also requires NFS  + +Role Variables +-------------- + +From this role: +| Name                                            | Default value         |                                                             | +|-------------------------------------------------|-----------------------|-------------------------------------------------------------| +| openshift_hosted_metrics_deploy                 | False                 | If metrics should be deployed                               | +| openshift_hosted_metrics_storage_nfs_directory  | /exports              | Root export directory.                                      | +| openshift_hosted_metrics_storage_volume_name    | metrics               | Metrics volume within openshift_hosted_metrics_volume_dir   | +| openshift_hosted_metrics_storage_volume_size    | 10Gi                  | Metrics volume size                                         | +| openshift_hosted_metrics_storage_nfs_options    | *(rw,root_squash)     | NFS options for configured exports.                         | + + +From openshift_common: +| Name                                  | Default Value  |                                        | +|---------------------------------------|----------------|----------------------------------------| +| openshift_master_default_subdomain    | null           | Subdomain FQDN (Mandatory)             | + + +Dependencies +------------ +openshift_facts +openshift_examples + +Example Playbook +---------------- + +- name: Configure openshift-metrics +  hosts: oo_first_master +  roles: +  - role: openshift_metrics + +License +------- + +Apache License, Version 2.0 + +Author Information +------------------ + +Jose David MartÃn (j.david.nieto@gmail.com) diff --git a/roles/openshift_metrics/meta/main.yaml b/roles/openshift_metrics/meta/main.yaml new file mode 100644 index 000000000..5f8d4f5c5 --- /dev/null +++ b/roles/openshift_metrics/meta/main.yaml @@ -0,0 +1,3 @@ +dependencies: +- { role: openshift_examples } +- { role: openshift_facts }
\ No newline at end of file diff --git a/roles/openshift_metrics/tasks/main.yaml b/roles/openshift_metrics/tasks/main.yaml new file mode 100644 index 000000000..1a86cb1ea --- /dev/null +++ b/roles/openshift_metrics/tasks/main.yaml @@ -0,0 +1,55 @@ +--- +- name: Copy Configuration to temporary conf +  command: > +    cp {{ openshift.common.config_base }}/master/admin.kubeconfig {{hawkular_tmp_conf}} +  changed_when: false + +- name: Create metrics-deployer Service Account +  shell: > +    echo {{ deployer_service_account | to_json | quote }} | +    {{ openshift.common.client_binary }} create +    -n openshift-infra +    --config={{hawkular_tmp_conf}} +    -f - +  register: deployer_create_service_account +  failed_when: "'already exists' not in deployer_create_service_account.stderr and deployer_create_service_account.rc != 0" +  changed_when: deployer_create_service_account.rc == 0 + +- name: Create metrics-deployer Secret +  command: > +    {{ openshift.common.client_binary }} +    secrets new metrics-deployer +    nothing=/dev/null +    -n openshift-infra +  register: deployer_create_secret +  failed_when: "'already exists' not in deployer_create_secret.stderr and deployer_create_secret.rc !=0" +  changed_when: deployer_create_secret.rc == 0 + +- name: Configure role/user permissions +  command: > +    {{ openshift.common.admin_binary }} {{item}} +    --config={{hawkular_tmp_conf}} +  with_items: "{{hawkular_permission_oc_commands}}" +  register: hawkular_perm_task +  failed_when: "'already exists' not in hawkular_perm_task.stderr and hawkular_perm_task.rc != 0" +  changed_when: hawkular_perm_task.rc == 0 + +- name: Check openshift_master_default_subdomain +  fail:  +    msg: "Default subdomain should be defined" +  when: openshift.master.default_subdomain is not defined + +- name: Create Heapster and Hawkular/Cassandra Services +  shell: > +   {{ openshift.common.client_binary }} process -f \ +   /usr/share/openshift/examples/infrastructure-templates/{{ hawkular_type }}/metrics-deployer.yaml -v \ +    HAWKULAR_METRICS_HOSTNAME=hawkular-metrics.{{ openshift.master.default_subdomain }},USE_PERSISTENT_STORAGE={{ hawkular_persistence }} | \ +    {{ openshift.common.client_binary }} create -n openshift-infra -f -  +  register: oex_heapster_services +  failed_when: "'already exists' not in oex_heapster_services.stderr and oex_heapster_services.rc != 0" +  changed_when: false + +- name: Clean temporary config file +  command: > +    rm -rf {{hawkular_tmp_conf}} +  changed_when: false
\ No newline at end of file diff --git a/roles/openshift_metrics/vars/main.yaml b/roles/openshift_metrics/vars/main.yaml new file mode 100644 index 000000000..82d9d29f7 --- /dev/null +++ b/roles/openshift_metrics/vars/main.yaml @@ -0,0 +1,19 @@ +hawkular_permission_oc_commands: +    - policy add-role-to-user edit system:serviceaccount:openshift-infra:metrics-deployer -n openshift-infra +    - policy add-cluster-role-to-user cluster-admin system:serviceaccount:openshift-infra:heapster + +deployer_service_account: +    apiVersion: v1 +    kind: ServiceAccount +    metadata: +      name: metrics-deployer +    secrets: +    - name: metrics-deployer + + +hawkular_tmp_conf: /tmp/hawkular_admin.kubeconfig + +hawkular_persistence: "{% if openshift.hosted.metrics.storage.kind != None %}true{% else %}false{% endif %}" + +hawkular_type: "{{ 'origin' if deployment_type == 'origin' else 'enterprise' }}" + diff --git a/roles/openshift_node/meta/main.yml b/roles/openshift_node/meta/main.yml index 84ba9ac2e..ca0c332ea 100644 --- a/roles/openshift_node/meta/main.yml +++ b/roles/openshift_node/meta/main.yml @@ -15,3 +15,6 @@ dependencies:  - role: openshift_docker  - role: openshift_cloud_provider  - role: openshift_common +- role: openshift_node_dnsmasq +  when: openshift.common.use_dnsmasq + diff --git a/roles/openshift_node/tasks/main.yml b/roles/openshift_node/tasks/main.yml index 8987e0191..06fde88af 100644 --- a/roles/openshift_node/tasks/main.yml +++ b/roles/openshift_node/tasks/main.yml @@ -9,13 +9,6 @@      role: "{{ item.role }}"      local_facts: "{{ item.local_facts }}"    with_items: -  - role: common -    local_facts: -      # TODO: Replace this with a lookup or filter plugin. -      # TODO: Move this to the node role -      dns_ip: "{{ openshift_dns_ip -                  | default(openshift_master_cluster_vip -                  | default(None if openshift.common.version_gte_3_1_or_1_1 | bool else openshift_node_first_master_ip | default(None, true), true), true) }}"    - role: node      local_facts:        annotations: "{{ openshift_node_annotations | default(none) }}" @@ -32,6 +25,7 @@        ovs_image: "{{ osn_ovs_image | default(None) }}"        proxy_mode: "{{ openshift_node_proxy_mode | default('iptables') }}"        local_quota_per_fsgroup: "{{ openshift_node_local_quota_per_fsgroup | default(None) }}" +      dns_ip: "{{ openshift_dns_ip | default(none) | get_dns_ip(hostvars[inventory_hostname])}}"  # We have to add tuned-profiles in the same transaction otherwise we run into depsolving  # problems because the rpms don't pin the version properly. This was fixed in 3.1 packaging. diff --git a/roles/openshift_node/templates/node.yaml.v1.j2 b/roles/openshift_node/templates/node.yaml.v1.j2 index 28cb1ea26..9ba1a01dd 100644 --- a/roles/openshift_node/templates/node.yaml.v1.j2 +++ b/roles/openshift_node/templates/node.yaml.v1.j2 @@ -1,8 +1,8 @@  allowDisabledDocker: false  apiVersion: v1  dnsDomain: {{ openshift.common.dns_domain }} -{% if 'dns_ip' in openshift.common %} -dnsIP: {{ openshift.common.dns_ip }} +{% if 'dns_ip' in openshift.node %} +dnsIP: {{ openshift.node.dns_ip }}  {% endif %}  dockerConfig:    execHandlerName: "" diff --git a/roles/openshift_node_dnsmasq/files/networkmanager/99-origin-dns.sh b/roles/openshift_node_dnsmasq/files/networkmanager/99-origin-dns.sh new file mode 100755 index 000000000..51e0751e9 --- /dev/null +++ b/roles/openshift_node_dnsmasq/files/networkmanager/99-origin-dns.sh @@ -0,0 +1,55 @@ +#!/bin/bash -x + +# This NetworkManager dispatcher script replicates the functionality of +# NetworkManager's dns=dnsmasq  however, rather than hardcoding the listening +# address and /etc/resolv.conf to 127.0.0.1 it pulls the IP address from the +# interface that owns the default route. This enables us to then configure pods +# to use this IP address as their only resolver, where as using 127.0.0.1 inside +# a pod would fail. +# +# To use this, +# Drop this script in /etc/NetworkManager/dispatcher.d/ +# systemctl restart NetworkManager +# Configure node-config.yaml to set dnsIP: to the ip address of this +# node +# +# Test it: +# host kubernetes.default.svc.cluster.local +# host google.com +# +# TODO: I think this would be easy to add as a config option in NetworkManager +# natively, look at hacking that up + +cd /etc/sysconfig/network-scripts +. ./network-functions + +[ -f ../network ] && . ../network + +if [[ $2 =~ ^(up|dhcp4-change)$ ]]; then +  # couldn't find an existing method to determine if the interface owns the  +  # default route +  def_route=$(/sbin/ip route list match 0.0.0.0/0 | awk '{print $3 }') +  def_route_int=$(/sbin/ip route get to ${def_route} | awk '{print $3}') +  def_route_ip=$(/sbin/ip route get to ${def_route} | awk '{print $5}') +  if [[ ${DEVICE_IFACE} == ${def_route_int} ]]; then +    if [ ! -f /etc/dnsmasq.d/origin-dns.conf ]; then +      cat << EOF > /etc/dnsmasq.d/origin-dns.conf +strict-order +no-resolv +domain-needed +server=/cluster.local/172.30.0.1 +server=/30.172.in-addr.arpa/172.30.0.1 +EOF +    fi +    # zero out our upstream servers list and feed it into dnsmasq +    echo '' > /etc/dnsmasq.d/origin-upstream-dns.conf +    for ns in ${DHCP4_DOMAIN_NAME_SERVERS}; do +       echo "server=${ns}" >> /etc/dnsmasq.d/origin-upstream-dns.conf +    done +    echo "listen-address=${def_route_ip}" >> /etc/dnsmasq.d/origin-upstream-dns.conf +    systemctl restart dnsmasq + +    sed -i 's/^nameserver.*$/nameserver '"${def_route_ip}"'/g' /etc/resolv.conf +    echo "# nameserver updated by /etc/NetworkManager/dispatcher.d/99-origin-dns.sh" >> /etc/resolv.conf +  fi +fi diff --git a/roles/openshift_node_dnsmasq/handlers/main.yml b/roles/openshift_node_dnsmasq/handlers/main.yml new file mode 100644 index 000000000..7e9e4d299 --- /dev/null +++ b/roles/openshift_node_dnsmasq/handlers/main.yml @@ -0,0 +1,5 @@ +--- +- name: restart NetworkManager +  service:  +    name: NetworkManager +    state: restarted diff --git a/roles/openshift_node_dnsmasq/meta/main.yml b/roles/openshift_node_dnsmasq/meta/main.yml new file mode 100644 index 000000000..c83d64ae4 --- /dev/null +++ b/roles/openshift_node_dnsmasq/meta/main.yml @@ -0,0 +1,15 @@ +--- +galaxy_info: +  author: Scott Dodson +  description: OpenShift Node DNSMasq support +  company: Red Hat, Inc. +  license: Apache License, Version 2.0 +  min_ansible_version: 1.7 +  platforms: +  - name: EL +    versions: +    - 7 +  categories: +  - cloud +dependencies: +- role: openshift_common diff --git a/roles/openshift_node_dnsmasq/tasks/main.yml b/roles/openshift_node_dnsmasq/tasks/main.yml new file mode 100644 index 000000000..4cb24469d --- /dev/null +++ b/roles/openshift_node_dnsmasq/tasks/main.yml @@ -0,0 +1,27 @@ +--- +- name: Check for NetworkManager service +  command: > +    systemctl show NetworkManager +  register: nm_show +   +- name: Set fact using_network_manager +  set_fact: +    network_manager_active: "{{ True if 'ActiveState=active' in nm_show.stdout else False }}" +     +- name: Install dnsmasq +  action: "{{ ansible_pkg_mgr }} name=dnsmasq state=installed" +  when: not openshift.common.is_atomic | bool +   +- name: Install dnsmasq configuration +  template: +    src: origin-dns.conf.j2 +    dest: /etc/dnsmasq.d/origin-dns.conf + +# Dynamic NetworkManager based dispatcher +- include: ./network-manager.yml +  when: network_manager_active | bool +   +# Relies on ansible in order to configure static config +- include: ./no-network-manager.yml +  when: not network_manager_active | bool +   diff --git a/roles/openshift_node_dnsmasq/tasks/network-manager.yml b/roles/openshift_node_dnsmasq/tasks/network-manager.yml new file mode 100644 index 000000000..dddcfc9da --- /dev/null +++ b/roles/openshift_node_dnsmasq/tasks/network-manager.yml @@ -0,0 +1,9 @@ +--- +- name: Install network manager dispatch script +  copy: +    src: networkmanager/99-origin-dns.sh +    dest: /etc/NetworkManager/dispatcher.d/ +    mode: 0755 +  notify: restart NetworkManager + +- meta: flush_handlers diff --git a/roles/openshift_node_dnsmasq/tasks/no-network-manager.yml b/roles/openshift_node_dnsmasq/tasks/no-network-manager.yml new file mode 100644 index 000000000..cda90bd10 --- /dev/null +++ b/roles/openshift_node_dnsmasq/tasks/no-network-manager.yml @@ -0,0 +1,2 @@ +--- +- fail: msg="Not implemented"
\ No newline at end of file diff --git a/roles/openshift_node_dnsmasq/templates/origin-dns.conf.j2 b/roles/openshift_node_dnsmasq/templates/origin-dns.conf.j2 new file mode 100644 index 000000000..1753bb821 --- /dev/null +++ b/roles/openshift_node_dnsmasq/templates/origin-dns.conf.j2 @@ -0,0 +1,4 @@ +strict-order +no-resolv +domain-needed +server=/{{ openshift.common.dns_domain }}/{{ openshift.common.kube_svc_ip }} diff --git a/roles/openshift_storage_nfs/defaults/main.yml b/roles/openshift_storage_nfs/defaults/main.yml index 5f6893129..90592e9d0 100644 --- a/roles/openshift_storage_nfs/defaults/main.yml +++ b/roles/openshift_storage_nfs/defaults/main.yml @@ -8,6 +8,14 @@ openshift:            options: "*(rw,root_squash)"          volume:            name: "registry" +    metrics: +      deploy: False +      storage: +        nfs: +          directory: "/exports" +          options: "*(rw,root_squash)" +        volume: +          name: "metrics"  os_firewall_use_firewalld: False  os_firewall_allow:  - service: nfs | 
