Browse Source

Merge remote-tracking branch 'upstream/master' into upgrade

Devan Goodwin 9 years ago
parent
commit
9d05b8c192

+ 0 - 3
README_OSE.md

@@ -79,9 +79,6 @@ ansible_ssh_user=root
 # To deploy origin, change deployment_type to origin
 # To deploy origin, change deployment_type to origin
 deployment_type=enterprise
 deployment_type=enterprise
 
 
-# Pre-release registry URL
-oreg_url=rcm-img-docker01.build.eng.bos.redhat.com:5001/openshift3/ose-${component}:${version}
-
 # Pre-release additional repo
 # Pre-release additional repo
 openshift_additional_repos=[{'id': 'ose-devel', 'name': 'ose-devel',
 openshift_additional_repos=[{'id': 'ose-devel', 'name': 'ose-devel',
 'baseurl':
 'baseurl':

+ 1 - 1
inventory/byo/hosts.example

@@ -24,7 +24,7 @@ deployment_type=atomic-enterprise
 #use_cluster_metrics=true
 #use_cluster_metrics=true
 
 
 # Pre-release registry URL
 # Pre-release registry URL
-#oreg_url=rcm-img-docker01.build.eng.bos.redhat.com:5001/openshift3/ose-${component}:${version}
+#oreg_url=example.com/openshift3/ose-${component}:${version}
 
 
 # Pre-release Dev puddle repo
 # Pre-release Dev puddle repo
 #openshift_additional_repos=[{'id': 'ose-devel', 'name': 'ose-devel', 'baseurl': 'http://buildvm-devops.usersys.redhat.com/puddle/build/OpenShiftEnterprise/3.0/latest/RH7-RHOSE-3.0/$basearch/os', 'enabled': 1, 'gpgcheck': 0}]
 #openshift_additional_repos=[{'id': 'ose-devel', 'name': 'ose-devel', 'baseurl': 'http://buildvm-devops.usersys.redhat.com/puddle/build/OpenShiftEnterprise/3.0/latest/RH7-RHOSE-3.0/$basearch/os', 'enabled': 1, 'gpgcheck': 0}]

+ 1 - 1
roles/etcd/README.md

@@ -17,7 +17,7 @@ TODO
 Dependencies
 Dependencies
 ------------
 ------------
 
 
-None
+etcd-common
 
 
 Example Playbook
 Example Playbook
 ----------------
 ----------------

+ 0 - 8
roles/etcd/defaults/main.yaml

@@ -2,16 +2,8 @@
 etcd_interface: "{{ ansible_default_ipv4.interface }}"
 etcd_interface: "{{ ansible_default_ipv4.interface }}"
 etcd_client_port: 2379
 etcd_client_port: 2379
 etcd_peer_port: 2380
 etcd_peer_port: 2380
-etcd_peers_group: etcd
 etcd_url_scheme: http
 etcd_url_scheme: http
 etcd_peer_url_scheme: http
 etcd_peer_url_scheme: http
-etcd_conf_dir: /etc/etcd
-etcd_ca_file: "{{ etcd_conf_dir }}/ca.crt"
-etcd_cert_file: "{{ etcd_conf_dir }}/server.crt"
-etcd_key_file: "{{ etcd_conf_dir }}/server.key"
-etcd_peer_ca_file: "{{ etcd_conf_dir }}/ca.crt"
-etcd_peer_cert_file: "{{ etcd_conf_dir }}/peer.crt"
-etcd_peer_key_file: "{{ etcd_conf_dir }}/peer.key"
 
 
 etcd_initial_cluster_state: new
 etcd_initial_cluster_state: new
 etcd_initial_cluster_token: etcd-cluster-1
 etcd_initial_cluster_token: etcd-cluster-1

+ 1 - 0
roles/etcd/handlers/main.yml

@@ -1,3 +1,4 @@
 ---
 ---
 - name: restart etcd
 - name: restart etcd
   service: name=etcd state=restarted
   service: name=etcd state=restarted
+  when: not etcd_service_status_changed | default(false)

+ 1 - 1
roles/etcd/meta/main.yml

@@ -17,4 +17,4 @@ galaxy_info:
   - system
   - system
 dependencies:
 dependencies:
 - { role: os_firewall }
 - { role: os_firewall }
-- { role: openshift_repos }
+- { role: etcd_common }

+ 10 - 2
roles/etcd/tasks/main.yml

@@ -1,4 +1,12 @@
 ---
 ---
+- 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: Install etcd
 - name: Install etcd
   yum: pkg=etcd-2.* state=present
   yum: pkg=etcd-2.* state=present
 
 
@@ -49,5 +57,5 @@
     enabled: yes
     enabled: yes
   register: start_result
   register: start_result
 
 
-- pause: seconds=30
-  when: start_result | changed
+- set_fact:
+    etcd_service_status_changed = start_result | changed

+ 2 - 2
roles/etcd/templates/etcd.conf.j2

@@ -1,9 +1,9 @@
 {% macro initial_cluster() -%}
 {% macro initial_cluster() -%}
 {% for host in groups[etcd_peers_group] -%}
 {% for host in groups[etcd_peers_group] -%}
 {% if loop.last -%}
 {% if loop.last -%}
-{{ host }}={{ etcd_peer_url_scheme }}://{{ hostvars[host]['ansible_' + etcd_interface]['ipv4']['address'] }}:{{ etcd_peer_port }}
+{{ host }}={{ etcd_peer_url_scheme }}://{{ etcd_host_int_map[host].interface.ipv4.address }}:{{ etcd_peer_port }}
 {%- else -%}
 {%- else -%}
-{{ host }}={{ etcd_peer_url_scheme }}://{{ hostvars[host]['ansible_' + etcd_interface]['ipv4']['address'] }}:{{ etcd_peer_port }},
+{{ host }}={{ etcd_peer_url_scheme }}://{{ etcd_host_int_map[host].interface.ipv4.address }}:{{ etcd_peer_port }},
 {%- endif -%}
 {%- endif -%}
 {% endfor -%}
 {% endfor -%}
 {% endmacro -%}
 {% endmacro -%}

+ 1 - 1
roles/etcd_ca/meta/main.yml

@@ -13,4 +13,4 @@ galaxy_info:
   - cloud
   - cloud
   - system
   - system
 dependencies:
 dependencies:
-- { role: openshift_repos }
+- { role: etcd_common }

+ 15 - 15
roles/etcd_ca/tasks/main.yml

@@ -1,14 +1,14 @@
 ---
 ---
 - file:
 - file:
-    path: "{{ etcd_ca_dir }}/{{ item }}"
+    path: "{{ item }}"
     state: directory
     state: directory
     mode: 0700
     mode: 0700
     owner: root
     owner: root
     group: root
     group: root
   with_items:
   with_items:
-  - certs
-  - crl
-  - fragments
+  - "{{ etcd_ca_new_certs_dir }}"
+  - "{{ etcd_ca_crl_dir }}"
+  - "{{ etcd_ca_dir }}/fragments"
 
 
 - command: cp /etc/pki/tls/openssl.cnf ./
 - command: cp /etc/pki/tls/openssl.cnf ./
   args:
   args:
@@ -22,25 +22,25 @@
 
 
 - assemble:
 - assemble:
     src: "{{ etcd_ca_dir }}/fragments"
     src: "{{ etcd_ca_dir }}/fragments"
-    dest: "{{ etcd_ca_dir }}/openssl.cnf"
+    dest: "{{ etcd_openssl_conf }}"
 
 
-- command: touch index.txt
+- command: touch {{ etcd_ca_db }}
   args:
   args:
-    chdir: "{{ etcd_ca_dir }}"
-    creates: "{{ etcd_ca_dir }}/index.txt"
+    creates: "{{ etcd_ca_db }}"
 
 
 - copy:
 - copy:
-    dest: "{{ etcd_ca_dir }}/serial"
+    dest: "{{ etcd_ca_serial }}"
     content: "01"
     content: "01"
     force: no
     force: no
 
 
 - command: >
 - command: >
-    openssl req -config openssl.cnf -newkey rsa:4096
-    -keyout ca.key -new -out ca.crt -x509 -extensions etcd_v3_ca_self
-    -batch -nodes -subj /CN=etcd-signer@{{ ansible_date_time.epoch }}
-    -days 365
+    openssl req -config {{ etcd_openssl_conf }} -newkey rsa:4096
+    -keyout {{ etcd_ca_key }} -new -out {{ etcd_ca_cert }}
+    -x509 -extensions {{ etcd_ca_exts_self }} -batch -nodes
+    -days {{ etcd_ca_default_days }}
+    -subj /CN=etcd-signer@{{ ansible_date_time.epoch }}
   args:
   args:
     chdir: "{{ etcd_ca_dir }}"
     chdir: "{{ etcd_ca_dir }}"
-    creates: "{{ etcd_ca_dir }}/ca.crt"
+    creates: "{{ etcd_ca_cert }}"
   environment:
   environment:
-    SAN: ''
+    SAN: 'etcd-signer'

+ 15 - 15
roles/etcd_ca/templates/openssl_append.j2

@@ -1,20 +1,20 @@
 
 
-[ etcd_v3_req ]
+[ {{ etcd_req_ext }} ]
 basicConstraints = critical,CA:FALSE
 basicConstraints = critical,CA:FALSE
 keyUsage         = digitalSignature,keyEncipherment
 keyUsage         = digitalSignature,keyEncipherment
 subjectAltName   = ${ENV::SAN}
 subjectAltName   = ${ENV::SAN}
 
 
-[ etcd_ca ]
+[ {{ etcd_ca_name }} ]
 dir             = {{ etcd_ca_dir }}
 dir             = {{ etcd_ca_dir }}
-crl_dir         = $dir/crl
-database        = $dir/index.txt
-new_certs_dir   = $dir/certs
-certificate     = $dir/ca.crt
-serial          = $dir/serial
-private_key     = $dir/ca.key
-crl_number      = $dir/crlnumber
-x509_extensions = etcd_v3_ca_client
-default_days    = 365
+crl_dir         = {{ etcd_ca_crl_dir }}
+database        = {{ etcd_ca_db }}
+new_certs_dir   = {{ etcd_ca_new_certs_dir }}
+certificate     = {{ etcd_ca_cert }}
+serial          = {{ etcd_ca_serial }}
+private_key     = {{ etcd_ca_key }}
+crl_number      = {{ etcd_ca_crl_number }}
+x509_extensions = {{ etcd_ca_exts_client }}
+default_days    = {{ etcd_ca_default_days }}
 default_md      = sha256
 default_md      = sha256
 preserve        = no
 preserve        = no
 name_opt        = ca_default
 name_opt        = ca_default
@@ -23,27 +23,27 @@ policy          = policy_anything
 unique_subject  = no
 unique_subject  = no
 copy_extensions = copy
 copy_extensions = copy
 
 
-[ etcd_v3_ca_self ]
+[ {{ etcd_ca_exts_self }} ]
 authorityKeyIdentifier = keyid,issuer
 authorityKeyIdentifier = keyid,issuer
 basicConstraints       = critical,CA:TRUE,pathlen:0
 basicConstraints       = critical,CA:TRUE,pathlen:0
 keyUsage               = critical,digitalSignature,keyEncipherment,keyCertSign
 keyUsage               = critical,digitalSignature,keyEncipherment,keyCertSign
 subjectKeyIdentifier   = hash
 subjectKeyIdentifier   = hash
 
 
-[ etcd_v3_ca_peer ]
+[ {{ etcd_ca_exts_peer }} ]
 authorityKeyIdentifier = keyid,issuer:always
 authorityKeyIdentifier = keyid,issuer:always
 basicConstraints       = critical,CA:FALSE
 basicConstraints       = critical,CA:FALSE
 extendedKeyUsage       = clientAuth,serverAuth
 extendedKeyUsage       = clientAuth,serverAuth
 keyUsage               = digitalSignature,keyEncipherment
 keyUsage               = digitalSignature,keyEncipherment
 subjectKeyIdentifier   = hash
 subjectKeyIdentifier   = hash
 
 
-[ etcd_v3_ca_server ]
+[ {{ etcd_ca_exts_server }} ]
 authorityKeyIdentifier = keyid,issuer:always
 authorityKeyIdentifier = keyid,issuer:always
 basicConstraints       = critical,CA:FALSE
 basicConstraints       = critical,CA:FALSE
 extendedKeyUsage       = serverAuth
 extendedKeyUsage       = serverAuth
 keyUsage               = digitalSignature,keyEncipherment
 keyUsage               = digitalSignature,keyEncipherment
 subjectKeyIdentifier   = hash
 subjectKeyIdentifier   = hash
 
 
-[ etcd_v3_ca_client ]
+[ {{ etcd_ca_exts_client }} ]
 authorityKeyIdentifier = keyid,issuer:always
 authorityKeyIdentifier = keyid,issuer:always
 basicConstraints       = critical,CA:FALSE
 basicConstraints       = critical,CA:FALSE
 extendedKeyUsage       = clientAuth
 extendedKeyUsage       = clientAuth

+ 0 - 3
roles/etcd_ca/vars/main.yml

@@ -1,3 +0,0 @@
----
-etcd_conf_dir: /etc/etcd
-etcd_ca_dir: /etc/etcd/ca

+ 1 - 1
roles/etcd_certificates/tasks/client.yml

@@ -32,7 +32,7 @@
     creates: "{{ etcd_generated_certs_dir ~ '/' ~  item.etcd_cert_subdir ~ '/'
     creates: "{{ etcd_generated_certs_dir ~ '/' ~  item.etcd_cert_subdir ~ '/'
                  ~ item.etcd_cert_prefix ~ 'client.crt' }}"
                  ~ item.etcd_cert_prefix ~ 'client.crt' }}"
   environment:
   environment:
-    SAN: ''
+    SAN: "IP:{{ item.openshift.common.ip }}"
   with_items: etcd_needing_client_certs
   with_items: etcd_needing_client_certs
 
 
 - file:
 - file:

+ 0 - 3
roles/etcd_certificates/tasks/main.yml

@@ -4,6 +4,3 @@
 
 
 - include: server.yml
 - include: server.yml
   when: etcd_needing_server_certs is defined and etcd_needing_server_certs
   when: etcd_needing_server_certs is defined and etcd_needing_server_certs
-
-
-

+ 4 - 6
roles/etcd_certificates/tasks/server.yml

@@ -18,7 +18,7 @@
     creates: "{{ etcd_generated_certs_dir ~ '/' ~  item.etcd_cert_subdir ~ '/'
     creates: "{{ etcd_generated_certs_dir ~ '/' ~  item.etcd_cert_subdir ~ '/'
                  ~ item.etcd_cert_prefix ~ 'server.csr' }}"
                  ~ item.etcd_cert_prefix ~ 'server.csr' }}"
   environment:
   environment:
-    SAN: "IP:{{ item.openshift.common.ip }}"
+    SAN: "IP:{{ etcd_host_int_map[item.inventory_hostname].interface.ipv4.address }}"
   with_items: etcd_needing_server_certs
   with_items: etcd_needing_server_certs
 
 
 - name: Sign and create the server crt
 - name: Sign and create the server crt
@@ -32,7 +32,7 @@
     creates: "{{ etcd_generated_certs_dir ~ '/' ~  item.etcd_cert_subdir ~ '/'
     creates: "{{ etcd_generated_certs_dir ~ '/' ~  item.etcd_cert_subdir ~ '/'
                  ~ item.etcd_cert_prefix ~ 'server.crt' }}"
                  ~ item.etcd_cert_prefix ~ 'server.crt' }}"
   environment:
   environment:
-    SAN: ''
+    SAN: "IP:{{ etcd_host_int_map[item.inventory_hostname].interface.ipv4.address }}"
   with_items: etcd_needing_server_certs
   with_items: etcd_needing_server_certs
 
 
 - name: Create the peer csr
 - name: Create the peer csr
@@ -47,7 +47,7 @@
     creates: "{{ etcd_generated_certs_dir ~ '/' ~  item.etcd_cert_subdir ~ '/'
     creates: "{{ etcd_generated_certs_dir ~ '/' ~  item.etcd_cert_subdir ~ '/'
                  ~ item.etcd_cert_prefix ~ 'peer.csr' }}"
                  ~ item.etcd_cert_prefix ~ 'peer.csr' }}"
   environment:
   environment:
-    SAN: "IP:{{ item.openshift.common.ip }}"
+    SAN: "IP:{{ etcd_host_int_map[item.inventory_hostname].interface.ipv4.address }}"
   with_items: etcd_needing_server_certs
   with_items: etcd_needing_server_certs
 
 
 - name: Sign and create the peer crt
 - name: Sign and create the peer crt
@@ -61,7 +61,7 @@
     creates: "{{ etcd_generated_certs_dir ~ '/' ~  item.etcd_cert_subdir ~ '/'
     creates: "{{ etcd_generated_certs_dir ~ '/' ~  item.etcd_cert_subdir ~ '/'
                  ~ item.etcd_cert_prefix ~ 'peer.crt' }}"
                  ~ item.etcd_cert_prefix ~ 'peer.crt' }}"
   environment:
   environment:
-    SAN: ''
+    SAN: "IP:{{ etcd_host_int_map[item.inventory_hostname].interface.ipv4.address }}"
   with_items: etcd_needing_server_certs
   with_items: etcd_needing_server_certs
 
 
 - file:
 - file:
@@ -69,5 +69,3 @@
     dest: "{{ etcd_generated_certs_dir}}/{{ item.etcd_cert_subdir }}/{{ item.etcd_cert_prefix }}ca.crt"
     dest: "{{ etcd_generated_certs_dir}}/{{ item.etcd_cert_subdir }}/{{ item.etcd_cert_prefix }}ca.crt"
     state: hard
     state: hard
   with_items: etcd_needing_server_certs
   with_items: etcd_needing_server_certs
-
-

+ 0 - 11
roles/etcd_certificates/vars/main.yml

@@ -1,11 +0,0 @@
----
-etcd_conf_dir: /etc/etcd
-etcd_ca_dir: /etc/etcd/ca
-etcd_generated_certs_dir: /etc/etcd/generated_certs
-etcd_ca_cert: "{{ etcd_ca_dir }}/ca.crt"
-etcd_ca_key: "{{ etcd_ca_dir }}/ca.key"
-etcd_openssl_conf: "{{ etcd_ca_dir }}/openssl.cnf"
-etcd_ca_name: etcd_ca
-etcd_req_ext: etcd_v3_req
-etcd_ca_exts_peer: etcd_v3_ca_peer
-etcd_ca_exts_server: etcd_v3_ca_server

+ 34 - 0
roles/etcd_common/README.md

@@ -0,0 +1,34 @@
+etcd_common
+========================
+
+TODO
+
+Requirements
+------------
+
+TODO
+
+Role Variables
+--------------
+
+TODO
+
+Dependencies
+------------
+
+openshift-repos
+
+Example Playbook
+----------------
+
+TODO
+
+License
+-------
+
+Apache License Version 2.0
+
+Author Information
+------------------
+
+Jason DeTiberus (jdetiber@redhat.com)

+ 30 - 0
roles/etcd_common/defaults/main.yml

@@ -0,0 +1,30 @@
+---
+etcd_peers_group: etcd
+
+# etcd server vars
+etcd_conf_dir: /etc/etcd
+etcd_ca_file: "{{ etcd_conf_dir }}/ca.crt"
+etcd_cert_file: "{{ etcd_conf_dir }}/server.crt"
+etcd_key_file: "{{ etcd_conf_dir }}/server.key"
+etcd_peer_ca_file: "{{ etcd_conf_dir }}/ca.crt"
+etcd_peer_cert_file: "{{ etcd_conf_dir }}/peer.crt"
+etcd_peer_key_file: "{{ etcd_conf_dir }}/peer.key"
+
+# etcd ca vars
+etcd_ca_dir: "{{ etcd_conf_dir}}/ca"
+etcd_generated_certs_dir: "{{ etcd_conf_dir }}/generated_certs"
+etcd_ca_cert: "{{ etcd_ca_dir }}/ca.crt"
+etcd_ca_key: "{{ etcd_ca_dir }}/ca.key"
+etcd_openssl_conf: "{{ etcd_ca_dir }}/openssl.cnf"
+etcd_ca_name: etcd_ca
+etcd_req_ext: etcd_v3_req
+etcd_ca_exts_peer: etcd_v3_ca_peer
+etcd_ca_exts_server: etcd_v3_ca_server
+etcd_ca_exts_self: etcd_v3_ca_self
+etcd_ca_exts_client: etcd_v3_ca_client
+etcd_ca_crl_dir: "{{ etcd_ca_dir }}/crl"
+etcd_ca_new_certs_dir: "{{ etcd_ca_dir }}/certs"
+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

+ 16 - 0
roles/etcd_common/meta/main.yml

@@ -0,0 +1,16 @@
+---
+galaxy_info:
+  author: Jason DeTiberus
+  description:
+  company: Red Hat, Inc.
+  license: Apache License, Version 2.0
+  min_ansible_version: 1.9
+  platforms:
+  - name: EL
+    versions:
+    - 7
+  categories:
+  - cloud
+  - system
+dependencies:
+- { role: openshift_repos }

+ 13 - 0
roles/etcd_common/tasks/main.yml

@@ -0,0 +1,13 @@
+---
+- 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
+
+- 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

+ 13 - 0
roles/etcd_common/templates/host_int_map.j2

@@ -0,0 +1,13 @@
+---
+{% 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 %}

+ 10 - 0
roles/openshift_facts/library/openshift_facts.py

@@ -22,6 +22,7 @@ import copy
 import os
 import os
 from distutils.util import strtobool
 from distutils.util import strtobool
 from distutils.version import LooseVersion
 from distutils.version import LooseVersion
+from netaddr import IPNetwork
 
 
 
 
 def hostname_valid(hostname):
 def hostname_valid(hostname):
@@ -486,12 +487,21 @@ def set_aggregate_facts(facts):
     if 'common' in facts:
     if 'common' in facts:
         all_hostnames.add(facts['common']['hostname'])
         all_hostnames.add(facts['common']['hostname'])
         all_hostnames.add(facts['common']['public_hostname'])
         all_hostnames.add(facts['common']['public_hostname'])
+        all_hostnames.add(facts['common']['ip'])
+        all_hostnames.add(facts['common']['public_ip'])
 
 
         if 'master' in facts:
         if 'master' in facts:
+            # FIXME: not sure why but facts['dns']['domain'] fails
+            cluster_domain = 'cluster.local'
             if 'cluster_hostname' in facts['master']:
             if 'cluster_hostname' in facts['master']:
                 all_hostnames.add(facts['master']['cluster_hostname'])
                 all_hostnames.add(facts['master']['cluster_hostname'])
             if 'cluster_public_hostname' in facts['master']:
             if 'cluster_public_hostname' in facts['master']:
                 all_hostnames.add(facts['master']['cluster_public_hostname'])
                 all_hostnames.add(facts['master']['cluster_public_hostname'])
+            all_hostnames.update(['openshift', 'openshift.default', 'openshift.default.svc',
+                                  'openshift.default.svc.' + cluster_domain, 'kubernetes', 'kubernetes.default',
+                                  'kubernetes.default.svc', 'kubernetes.default.svc.' + cluster_domain])
+            first_svc_ip = str(IPNetwork(facts['master']['portal_net'])[1])
+            all_hostnames.add(first_svc_ip)
 
 
             if facts['master']['embedded_etcd']:
             if facts['master']['embedded_etcd']:
                 facts['master']['etcd_data_dir'] = os.path.join(
                 facts['master']['etcd_data_dir'] = os.path.join(

+ 3 - 0
roles/openshift_facts/tasks/main.yml

@@ -6,5 +6,8 @@
     - ansible_version | version_compare('1.9.0', 'ne')
     - ansible_version | version_compare('1.9.0', 'ne')
     - ansible_version | version_compare('1.9.0.1', 'ne')
     - ansible_version | version_compare('1.9.0.1', 'ne')
 
 
+- name: Ensure python-netaddr is installed
+  yum: pkg=python-netaddr state=installed
+
 - name: Gather Cluster facts
 - name: Gather Cluster facts
   openshift_facts:
   openshift_facts:

+ 2 - 0
roles/openshift_master_certificates/tasks/main.yml

@@ -34,6 +34,8 @@
     - serviceaccounts.private.key
     - serviceaccounts.private.key
     - serviceaccounts.public.key
     - serviceaccounts.public.key
 
 
+- debug: msg="{{ item.openshift.master.all_hostnames | join (',') }}"
+  with_items: masters_needing_certs
 
 
 - name: Create the master certificates if they do not already exist
 - name: Create the master certificates if they do not already exist
   command: >
   command: >

+ 82 - 0
roles/os_zabbix/vars/template_openshift_master.yml

@@ -31,6 +31,78 @@ g_template_openshift_master:
     applications:
     applications:
     - Openshift Master
     - Openshift Master
 
 
+  - key: openshift.master.etcd.create.success
+    description: Show number of successful create actions
+    type: int
+    applications:
+    - Openshift Etcd
+
+  - key: openshift.master.etcd.create.fail
+    description: Show number of failed create actions
+    type: int
+    applications:
+    - Openshift Etcd
+
+  - key: openshift.master.etcd.delete.success
+    description: Show number of successful delete actions
+    type: int
+    applications:
+    - Openshift Etcd
+
+  - key: openshift.master.etcd.delete.fail
+    description: Show number of failed delete actions
+    type: int
+    applications:
+    - Openshift Etcd
+
+  - key: openshift.master.etcd.get.success
+    description: Show number of successful get actions
+    type: int
+    applications:
+    - Openshift Etcd
+
+  - key: openshift.master.etcd.get.fail
+    description: Show number of failed get actions
+    type: int
+    applications:
+    - Openshift Etcd
+
+  - key: openshift.master.etcd.set.success
+    description: Show number of successful set actions
+    type: int
+    applications:
+    - Openshift Etcd
+
+  - key: openshift.master.etcd.set.fail
+    description: Show number of failed set actions
+    type: int
+    applications:
+    - Openshift Etcd
+
+  - key: openshift.master.etcd.update.success
+    description: Show number of successful update actions
+    type: int
+    applications:
+    - Openshift Etcd
+
+  - key: openshift.master.etcd.update.fail
+    description: Show number of failed update actions
+    type: int
+    applications:
+    - Openshift Etcd
+
+  - key: openshift.master.etcd.watchers
+    description: Show number of etcd watchers
+    type: int
+    applications:
+    - Openshift Etcd
+
+  - key: openshift.master.etcd.ping
+    description: etcd ping
+    type: int
+    applications:
+    - Openshift Etcd
+
   ztriggers:
   ztriggers:
   - name: 'Application creation has failed on {HOST.NAME}'
   - name: 'Application creation has failed on {HOST.NAME}'
     expression: '{Template Openshift Master:create_app.last(#1)}=1 and {Template Openshift Master:create_app.last(#2)}=1'
     expression: '{Template Openshift Master:create_app.last(#1)}=1 and {Template Openshift Master:create_app.last(#2)}=1'
@@ -56,3 +128,13 @@ g_template_openshift_master:
     expression: '{Template Openshift Master:openshift.project.counter.last()}=0'
     expression: '{Template Openshift Master:openshift.project.counter.last()}=0'
     url: 'https://github.com/openshift/ops-sop/blob/master/V3/Alerts/openshift_master.asciidoc'
     url: 'https://github.com/openshift/ops-sop/blob/master/V3/Alerts/openshift_master.asciidoc'
     priority: info
     priority: info
+
+  - name: 'Low number of etcd watchers on {HOST.NAME}'
+    expression: '{Template Openshift Master:openshift.master.etcd.watchers.last(#1)}<10 and {Template Openshift Master:openshift.master.etcd.watchers.last(#2)}<10'
+    url: 'https://github.com/openshift/ops-sop/blob/master/V3/Alerts/check_etcd.asciidoc'
+    priority: avg
+
+  - name: 'Etcd ping failed on {HOST.NAME}'
+    expression: '{Template Openshift Master:openshift.master.etcd.ping.last(#1)}=0 and {Template Openshift Master:openshift.master.etcd.ping.last(#2)}=0'
+    url: 'https://github.com/openshift/ops-sop/blob/master/V3/Alerts/check_etcd.asciidoc'
+    priority: high

+ 17 - 17
utils/src/ooinstall/cli_installer.py

@@ -6,7 +6,7 @@ import click
 import os
 import os
 import re
 import re
 import sys
 import sys
-from ooinstall import install_transactions
+from ooinstall import openshift_ansible
 from ooinstall import OOConfig
 from ooinstall import OOConfig
 from ooinstall.oo_config import Host
 from ooinstall.oo_config import Host
 from ooinstall.variants import find_variant, get_variant_version_combos
 from ooinstall.variants import find_variant, get_variant_version_combos
@@ -95,7 +95,7 @@ The OpenShift Node provides the runtime environments for containers.  It will
 host the required services to be managed by the Master.
 host the required services to be managed by the Master.
 
 
 http://docs.openshift.com/enterprise/latest/architecture/infrastructure_components/kubernetes_infrastructure.html#master
 http://docs.openshift.com/enterprise/latest/architecture/infrastructure_components/kubernetes_infrastructure.html#master
-http://docs.openshift.com/enterprise/3.0/architecture/infrastructure_components/kubernetes_infrastructure.html#node
+http://docs.openshift.com/enterprise/latest/architecture/infrastructure_components/kubernetes_infrastructure.html#node
     """
     """
     click.echo(message)
     click.echo(message)
 
 
@@ -191,7 +191,7 @@ Notes:
     facts_confirmed = click.confirm("Do the above facts look correct?")
     facts_confirmed = click.confirm("Do the above facts look correct?")
     if not facts_confirmed:
     if not facts_confirmed:
         message = """
         message = """
-Edit %s with the desired values and re-run with --unattended .
+Edit %s with the desired values and rerun atomic-openshift-installer with --unattended .
 """ % oo_cfg.config_path
 """ % oo_cfg.config_path
         click.echo(message)
         click.echo(message)
         # Make sure we actually write out the config file.
         # Make sure we actually write out the config file.
@@ -357,8 +357,8 @@ def get_hosts_to_run_on(oo_cfg, callback_facts, unattended, force):
                 hosts_to_run_on.extend(new_nodes)
                 hosts_to_run_on.extend(new_nodes)
                 oo_cfg.hosts.extend(new_nodes)
                 oo_cfg.hosts.extend(new_nodes)
 
 
-                install_transactions.set_config(oo_cfg)
-                callback_facts, error = install_transactions.default_facts(oo_cfg.hosts)
+                openshift_ansible.set_config(oo_cfg)
+                callback_facts, error = openshift_ansible.default_facts(oo_cfg.hosts)
                 if error:
                 if error:
                     click.echo("There was a problem fetching the required information. " \
                     click.echo("There was a problem fetching the required information. " \
                                "See {} for details.".format(oo_cfg.settings['ansible_log_path']))
                                "See {} for details.".format(oo_cfg.settings['ansible_log_path']))
@@ -379,14 +379,14 @@ def get_hosts_to_run_on(oo_cfg, callback_facts, unattended, force):
         readable=True),
         readable=True),
     default=None)
     default=None)
 @click.option('--ansible-playbook-directory',
 @click.option('--ansible-playbook-directory',
-    '-a',
-    type=click.Path(exists=True,
-        file_okay=False,
-        dir_okay=True,
-        writable=False,
-        readable=True),
-    # callback=validate_ansible_dir,
-    envvar='OO_ANSIBLE_PLAYBOOK_DIRECTORY')
+              '-a',
+              type=click.Path(exists=True,
+                              file_okay=False,
+                              dir_okay=True,
+                              readable=True),
+              # callback=validate_ansible_dir,
+              default='/usr/share/openshift-ansible/',
+              envvar='OO_ANSIBLE_PLAYBOOK_DIRECTORY')
 @click.option('--ansible-config',
 @click.option('--ansible-config',
     type=click.Path(file_okay=True,
     type=click.Path(file_okay=True,
         dir_okay=False,
         dir_okay=False,
@@ -434,7 +434,7 @@ def cli(ctx, unattended, configuration, ansible_playbook_directory, ansible_conf
     oo_cfg.settings['ansible_log_path'] = ctx.obj['ansible_log_path']
     oo_cfg.settings['ansible_log_path'] = ctx.obj['ansible_log_path']
 
 
     ctx.obj['oo_cfg'] = oo_cfg
     ctx.obj['oo_cfg'] = oo_cfg
-    install_transactions.set_config(oo_cfg)
+    openshift_ansible.set_config(oo_cfg)
 
 
 
 
 @click.command()
 @click.command()
@@ -456,7 +456,7 @@ def uninstall(ctx):
             click.echo("Uninstall cancelled.")
             click.echo("Uninstall cancelled.")
             sys.exit(0)
             sys.exit(0)
 
 
-    install_transactions.run_uninstall_playbook()
+    openshift_ansible.run_uninstall_playbook()
 
 
 
 
 @click.command()
 @click.command()
@@ -509,7 +509,7 @@ def install(ctx, force):
         oo_cfg = get_missing_info_from_user(oo_cfg)
         oo_cfg = get_missing_info_from_user(oo_cfg)
 
 
     click.echo('Gathering information from hosts...')
     click.echo('Gathering information from hosts...')
-    callback_facts, error = install_transactions.default_facts(oo_cfg.hosts)
+    callback_facts, error = openshift_ansible.default_facts(oo_cfg.hosts)
     if error:
     if error:
         click.echo("There was a problem fetching the required information. " \
         click.echo("There was a problem fetching the required information. " \
                    "Please see {} for details.".format(oo_cfg.settings['ansible_log_path']))
                    "Please see {} for details.".format(oo_cfg.settings['ansible_log_path']))
@@ -536,7 +536,7 @@ If changes are needed to the values recorded by the installer please update {}.
     if not ctx.obj['unattended']:
     if not ctx.obj['unattended']:
         confirm_continue(message)
         confirm_continue(message)
 
 
-    error = install_transactions.run_main_playbook(oo_cfg.hosts,
+    error = openshift_ansible.run_main_playbook(oo_cfg.hosts,
                                                    hosts_to_run_on)
                                                    hosts_to_run_on)
     if error:
     if error:
         # The bootstrap script will print out the log location.
         # The bootstrap script will print out the log location.

+ 13 - 1
utils/src/ooinstall/install_transactions.py

@@ -2,7 +2,9 @@
 # repo. We will work on these over time.
 # repo. We will work on these over time.
 # pylint: disable=bad-continuation,missing-docstring,no-self-use,invalid-name,global-statement,global-variable-not-assigned
 # pylint: disable=bad-continuation,missing-docstring,no-self-use,invalid-name,global-statement,global-variable-not-assigned
 
 
+import socket
 import subprocess
 import subprocess
+import sys
 import os
 import os
 import yaml
 import yaml
 from ooinstall.variants import find_variant
 from ooinstall.variants import find_variant
@@ -15,13 +17,15 @@ def set_config(cfg):
 
 
 def generate_inventory(hosts):
 def generate_inventory(hosts):
     global CFG
     global CFG
+
+    installer_host = socket.gethostname()
     base_inventory_path = CFG.settings['ansible_inventory_path']
     base_inventory_path = CFG.settings['ansible_inventory_path']
     base_inventory = open(base_inventory_path, 'w')
     base_inventory = open(base_inventory_path, 'w')
     base_inventory.write('\n[OSEv3:children]\nmasters\nnodes\n')
     base_inventory.write('\n[OSEv3:children]\nmasters\nnodes\n')
     base_inventory.write('\n[OSEv3:vars]\n')
     base_inventory.write('\n[OSEv3:vars]\n')
     base_inventory.write('ansible_ssh_user={}\n'.format(CFG.settings['ansible_ssh_user']))
     base_inventory.write('ansible_ssh_user={}\n'.format(CFG.settings['ansible_ssh_user']))
     if CFG.settings['ansible_ssh_user'] != 'root':
     if CFG.settings['ansible_ssh_user'] != 'root':
-        base_inventory.write('ansible_sudo=true\n')
+        base_inventory.write('ansible_become=true\n')
 
 
     # Find the correct deployment type for ansible:
     # Find the correct deployment type for ansible:
     ver = find_variant(CFG.settings['variant'],
     ver = find_variant(CFG.settings['variant'],
@@ -40,6 +44,14 @@ def generate_inventory(hosts):
     if 'OO_INSTALL_STAGE_REGISTRY' in os.environ:
     if 'OO_INSTALL_STAGE_REGISTRY' in os.environ:
         base_inventory.write('oreg_url=registry.access.stage.redhat.com/openshift3/ose-${component}:${version}\n')
         base_inventory.write('oreg_url=registry.access.stage.redhat.com/openshift3/ose-${component}:${version}\n')
 
 
+    if any(host.hostname == installer_host or host.public_hostname == installer_host
+            for host in hosts):
+        no_pwd_sudo = subprocess.call(['sudo', '-v', '--non-interactive'])
+        if no_pwd_sudo == 1:
+            print 'The atomic-openshift-installer requires sudo access without a password.'
+            sys.exit(1)
+        base_inventory.write("ansible_connection=local\n")
+
     base_inventory.write('\n[masters]\n')
     base_inventory.write('\n[masters]\n')
     masters = (host for host in hosts if host.master)
     masters = (host for host in hosts if host.master)
     for master in masters:
     for master in masters:

+ 1 - 1
utils/src/ooinstall/variants.py

@@ -41,7 +41,7 @@ OSE = Variant('openshift-enterprise', 'OpenShift Enterprise',
     ]
     ]
 )
 )
 
 
-AEP = Variant('atomic-enterprise', 'Atomic OpenShift Enterprise',
+AEP = Variant('atomic-enterprise', 'Atomic Enterprise Platform',
     [
     [
         Version('3.1', 'atomic-enterprise')
         Version('3.1', 'atomic-enterprise')
     ]
     ]

+ 20 - 20
utils/test/cli_installer_tests.py

@@ -102,8 +102,8 @@ class UnattendedCliTests(OOCliFixture):
         OOCliFixture.setUp(self)
         OOCliFixture.setUp(self)
         self.cli_args.append("-u")
         self.cli_args.append("-u")
 
 
-    @patch('ooinstall.install_transactions.run_main_playbook')
-    @patch('ooinstall.install_transactions.load_system_facts')
+    @patch('ooinstall.openshift_ansible.run_main_playbook')
+    @patch('ooinstall.openshift_ansible.load_system_facts')
     def test_cfg_full_run(self, load_facts_mock, run_playbook_mock):
     def test_cfg_full_run(self, load_facts_mock, run_playbook_mock):
         load_facts_mock.return_value = (MOCK_FACTS, 0)
         load_facts_mock.return_value = (MOCK_FACTS, 0)
         run_playbook_mock.return_value = 0
         run_playbook_mock.return_value = 0
@@ -133,8 +133,8 @@ class UnattendedCliTests(OOCliFixture):
         self.assertEquals(3, len(hosts))
         self.assertEquals(3, len(hosts))
         self.assertEquals(3, len(hosts_to_run_on))
         self.assertEquals(3, len(hosts_to_run_on))
 
 
-    @patch('ooinstall.install_transactions.run_main_playbook')
-    @patch('ooinstall.install_transactions.load_system_facts')
+    @patch('ooinstall.openshift_ansible.run_main_playbook')
+    @patch('ooinstall.openshift_ansible.load_system_facts')
     def test_inventory_write(self, load_facts_mock, run_playbook_mock):
     def test_inventory_write(self, load_facts_mock, run_playbook_mock):
 
 
         # Add an ssh user so we can verify it makes it to the inventory file:
         # Add an ssh user so we can verify it makes it to the inventory file:
@@ -172,8 +172,8 @@ class UnattendedCliTests(OOCliFixture):
             self.assertTrue('openshift_hostname' in master_line)
             self.assertTrue('openshift_hostname' in master_line)
             self.assertTrue('openshift_public_hostname' in master_line)
             self.assertTrue('openshift_public_hostname' in master_line)
 
 
-    @patch('ooinstall.install_transactions.run_main_playbook')
-    @patch('ooinstall.install_transactions.load_system_facts')
+    @patch('ooinstall.openshift_ansible.run_main_playbook')
+    @patch('ooinstall.openshift_ansible.load_system_facts')
     def test_variant_version_latest_assumed(self, load_facts_mock,
     def test_variant_version_latest_assumed(self, load_facts_mock,
         run_playbook_mock):
         run_playbook_mock):
         load_facts_mock.return_value = (MOCK_FACTS, 0)
         load_facts_mock.return_value = (MOCK_FACTS, 0)
@@ -199,8 +199,8 @@ class UnattendedCliTests(OOCliFixture):
         self.assertEquals('openshift-enterprise',
         self.assertEquals('openshift-enterprise',
             inventory.get('OSEv3:vars', 'deployment_type'))
             inventory.get('OSEv3:vars', 'deployment_type'))
 
 
-    @patch('ooinstall.install_transactions.run_main_playbook')
-    @patch('ooinstall.install_transactions.load_system_facts')
+    @patch('ooinstall.openshift_ansible.run_main_playbook')
+    @patch('ooinstall.openshift_ansible.load_system_facts')
     def test_variant_version_preserved(self, load_facts_mock,
     def test_variant_version_preserved(self, load_facts_mock,
         run_playbook_mock):
         run_playbook_mock):
         load_facts_mock.return_value = (MOCK_FACTS, 0)
         load_facts_mock.return_value = (MOCK_FACTS, 0)
@@ -227,8 +227,8 @@ class UnattendedCliTests(OOCliFixture):
         self.assertEquals('enterprise',
         self.assertEquals('enterprise',
             inventory.get('OSEv3:vars', 'deployment_type'))
             inventory.get('OSEv3:vars', 'deployment_type'))
 
 
-    @patch('ooinstall.install_transactions.run_ansible')
-    @patch('ooinstall.install_transactions.load_system_facts')
+    @patch('ooinstall.openshift_ansible.run_ansible')
+    @patch('ooinstall.openshift_ansible.load_system_facts')
     def test_no_ansible_config_specified(self, load_facts_mock, run_ansible_mock):
     def test_no_ansible_config_specified(self, load_facts_mock, run_ansible_mock):
         load_facts_mock.return_value = (MOCK_FACTS, 0)
         load_facts_mock.return_value = (MOCK_FACTS, 0)
         run_ansible_mock.return_value = 0
         run_ansible_mock.return_value = 0
@@ -238,8 +238,8 @@ class UnattendedCliTests(OOCliFixture):
         self._ansible_config_test(load_facts_mock, run_ansible_mock,
         self._ansible_config_test(load_facts_mock, run_ansible_mock,
             config, None, None)
             config, None, None)
 
 
-    @patch('ooinstall.install_transactions.run_ansible')
-    @patch('ooinstall.install_transactions.load_system_facts')
+    @patch('ooinstall.openshift_ansible.run_ansible')
+    @patch('ooinstall.openshift_ansible.load_system_facts')
     def test_ansible_config_specified_cli(self, load_facts_mock, run_ansible_mock):
     def test_ansible_config_specified_cli(self, load_facts_mock, run_ansible_mock):
         load_facts_mock.return_value = (MOCK_FACTS, 0)
         load_facts_mock.return_value = (MOCK_FACTS, 0)
         run_ansible_mock.return_value = 0
         run_ansible_mock.return_value = 0
@@ -250,8 +250,8 @@ class UnattendedCliTests(OOCliFixture):
         self._ansible_config_test(load_facts_mock, run_ansible_mock,
         self._ansible_config_test(load_facts_mock, run_ansible_mock,
             config, ansible_config, ansible_config)
             config, ansible_config, ansible_config)
 
 
-    @patch('ooinstall.install_transactions.run_ansible')
-    @patch('ooinstall.install_transactions.load_system_facts')
+    @patch('ooinstall.openshift_ansible.run_ansible')
+    @patch('ooinstall.openshift_ansible.load_system_facts')
     def test_ansible_config_specified_in_installer_config(self,
     def test_ansible_config_specified_in_installer_config(self,
         load_facts_mock, run_ansible_mock):
         load_facts_mock, run_ansible_mock):
 
 
@@ -389,8 +389,8 @@ class AttendedCliTests(OOCliFixture):
             self.assertTrue('public_ip' in h)
             self.assertTrue('public_ip' in h)
             self.assertTrue('public_hostname' in h)
             self.assertTrue('public_hostname' in h)
 
 
-    @patch('ooinstall.install_transactions.run_main_playbook')
-    @patch('ooinstall.install_transactions.load_system_facts')
+    @patch('ooinstall.openshift_ansible.run_main_playbook')
+    @patch('ooinstall.openshift_ansible.load_system_facts')
     def test_full_run(self, load_facts_mock, run_playbook_mock):
     def test_full_run(self, load_facts_mock, run_playbook_mock):
         load_facts_mock.return_value = (MOCK_FACTS, 0)
         load_facts_mock.return_value = (MOCK_FACTS, 0)
         run_playbook_mock.return_value = 0
         run_playbook_mock.return_value = 0
@@ -413,8 +413,8 @@ class AttendedCliTests(OOCliFixture):
         written_config = self._read_yaml(self.config_file)
         written_config = self._read_yaml(self.config_file)
         self._verify_config_hosts(written_config, 3)
         self._verify_config_hosts(written_config, 3)
 
 
-    @patch('ooinstall.install_transactions.run_main_playbook')
-    @patch('ooinstall.install_transactions.load_system_facts')
+    @patch('ooinstall.openshift_ansible.run_main_playbook')
+    @patch('ooinstall.openshift_ansible.load_system_facts')
     def test_add_nodes(self, load_facts_mock, run_playbook_mock):
     def test_add_nodes(self, load_facts_mock, run_playbook_mock):
 
 
         # Modify the mock facts to return a version indicating OpenShift
         # Modify the mock facts to return a version indicating OpenShift
@@ -446,8 +446,8 @@ class AttendedCliTests(OOCliFixture):
         written_config = self._read_yaml(self.config_file)
         written_config = self._read_yaml(self.config_file)
         self._verify_config_hosts(written_config, 3)
         self._verify_config_hosts(written_config, 3)
 
 
-    @patch('ooinstall.install_transactions.run_main_playbook')
-    @patch('ooinstall.install_transactions.load_system_facts')
+    @patch('ooinstall.openshift_ansible.run_main_playbook')
+    @patch('ooinstall.openshift_ansible.load_system_facts')
     def test_fresh_install_with_config(self, load_facts_mock, run_playbook_mock):
     def test_fresh_install_with_config(self, load_facts_mock, run_playbook_mock):
         load_facts_mock.return_value = (MOCK_FACTS, 0)
         load_facts_mock.return_value = (MOCK_FACTS, 0)
         run_playbook_mock.return_value = 0
         run_playbook_mock.return_value = 0