summaryrefslogtreecommitdiffstats
path: root/roles
diff options
context:
space:
mode:
authorThomas Wiest <twiest@users.noreply.github.com>2015-07-16 12:15:51 -0400
committerThomas Wiest <twiest@users.noreply.github.com>2015-07-16 12:15:51 -0400
commit68d6fdf1c1c8244b3bd2ccdf77499d9127592368 (patch)
tree0e28786664b825c97b33188bf36c42387fe59a51 /roles
parenta1fe1b25b588ba995192b99e44a7950ee0c6e032 (diff)
parentf831779404b0147d6a92935cd8b77de3e25f2bec (diff)
downloadopenshift-68d6fdf1c1c8244b3bd2ccdf77499d9127592368.tar.gz
openshift-68d6fdf1c1c8244b3bd2ccdf77499d9127592368.tar.bz2
openshift-68d6fdf1c1c8244b3bd2ccdf77499d9127592368.tar.xz
openshift-68d6fdf1c1c8244b3bd2ccdf77499d9127592368.zip
Merge pull request #341 from detiber/sdodson-etcd-playbook
External clustered etcd support
Diffstat (limited to 'roles')
-rw-r--r--roles/etcd/README.md39
-rw-r--r--roles/etcd/defaults/main.yaml31
-rw-r--r--roles/etcd/handlers/main.yml3
-rw-r--r--roles/etcd/meta/main.yml19
-rw-r--r--roles/etcd/tasks/main.yml52
-rw-r--r--roles/etcd/templates/etcd.conf.j252
-rw-r--r--roles/etcd_ca/README.md34
-rw-r--r--roles/etcd_ca/meta/main.yml16
-rw-r--r--roles/etcd_ca/tasks/main.yml44
-rw-r--r--roles/etcd_ca/templates/openssl_append.j251
-rw-r--r--roles/etcd_ca/vars/main.yml3
-rw-r--r--roles/etcd_certificates/README.md34
-rw-r--r--roles/etcd_certificates/meta/main.yml16
-rw-r--r--roles/etcd_certificates/tasks/client.yml42
-rw-r--r--roles/etcd_certificates/tasks/main.yml9
-rw-r--r--roles/etcd_certificates/tasks/server.yml73
-rw-r--r--roles/etcd_certificates/vars/main.yml11
-rwxr-xr-xroles/openshift_facts/library/openshift_facts.py22
-rw-r--r--roles/openshift_master/tasks/main.yml21
-rw-r--r--roles/openshift_master/templates/master.yaml.v1.j28
-rw-r--r--roles/openshift_master_ca/README.md34
-rw-r--r--roles/openshift_master_ca/meta/main.yml (renamed from roles/openshift_register_nodes/meta/main.yml)1
-rw-r--r--roles/openshift_master_ca/tasks/main.yml22
-rw-r--r--roles/openshift_master_ca/vars/main.yml5
-rw-r--r--roles/openshift_master_certificates/README.md34
-rw-r--r--roles/openshift_master_certificates/meta/main.yml16
-rw-r--r--roles/openshift_master_certificates/tasks/main.yml24
-rw-r--r--roles/openshift_master_certificates/vars/main.yml (renamed from roles/openshift_register_nodes/vars/main.yml)4
-rw-r--r--roles/openshift_node/tasks/main.yml14
-rw-r--r--roles/openshift_node/templates/node.yaml.v1.j24
-rw-r--r--roles/openshift_node_certificates/tasks/main.yml1
-rw-r--r--roles/openshift_node_certificates/vars/main.yml1
-rw-r--r--roles/openshift_register_nodes/README.md15
-rwxr-xr-xroles/openshift_register_nodes/library/kubernetes_register_node.py513
-rw-r--r--roles/openshift_register_nodes/tasks/main.yml53
35 files changed, 698 insertions, 623 deletions
diff --git a/roles/etcd/README.md b/roles/etcd/README.md
new file mode 100644
index 000000000..49207c428
--- /dev/null
+++ b/roles/etcd/README.md
@@ -0,0 +1,39 @@
+Role Name
+=========
+
+Configures an etcd cluster for an arbitrary number of hosts
+
+Requirements
+------------
+
+This role assumes it's being deployed on a RHEL/Fedora based host with package
+named 'etcd' available via yum.
+
+Role Variables
+--------------
+
+TODO
+
+Dependencies
+------------
+
+None
+
+Example Playbook
+----------------
+
+ - hosts: etcd
+ roles:
+ - { etcd }
+
+License
+-------
+
+MIT
+
+Author Information
+------------------
+
+Scott Dodson <sdodson@redhat.com>
+Adapted from https://github.com/retr0h/ansible-etcd for use on RHEL/Fedora. We
+should at some point submit a PR to merge this with that module.
diff --git a/roles/etcd/defaults/main.yaml b/roles/etcd/defaults/main.yaml
new file mode 100644
index 000000000..0fb45f37c
--- /dev/null
+++ b/roles/etcd/defaults/main.yaml
@@ -0,0 +1,31 @@
+---
+etcd_interface: eth0
+etcd_client_port: 2379
+etcd_peer_port: 2380
+etcd_peers_group: etcd
+etcd_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_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_data_dir: /var/lib/etcd/
+
+os_firewall_use_firewalld: False
+os_firewall_allow:
+- service: etcd
+ port: "{{etcd_client_port}}/tcp"
+- service: etcd peering
+ port: "{{ etcd_peer_port }}/tcp"
diff --git a/roles/etcd/handlers/main.yml b/roles/etcd/handlers/main.yml
new file mode 100644
index 000000000..b897913f9
--- /dev/null
+++ b/roles/etcd/handlers/main.yml
@@ -0,0 +1,3 @@
+---
+- name: restart etcd
+ service: name=etcd state=restarted
diff --git a/roles/etcd/meta/main.yml b/roles/etcd/meta/main.yml
new file mode 100644
index 000000000..82b1a62b8
--- /dev/null
+++ b/roles/etcd/meta/main.yml
@@ -0,0 +1,19 @@
+---
+# This module is based on https://github.com/retr0h/ansible-etcd with most
+# changes centered around installing from a pre-existing rpm
+# TODO: Extend https://github.com/retr0h/ansible-etcd rather than forking
+galaxy_info:
+ author: Scott Dodson
+ description: etcd management
+ company: Red Hat, Inc.
+ license: Apache License, Version 2.0
+ min_ansible_version: 1.2
+ platforms:
+ - name: EL
+ versions:
+ - 7
+ categories:
+ - cloud
+ - system
+dependencies:
+- { role: os_firewall }
diff --git a/roles/etcd/tasks/main.yml b/roles/etcd/tasks/main.yml
new file mode 100644
index 000000000..79a91dfde
--- /dev/null
+++ b/roles/etcd/tasks/main.yml
@@ -0,0 +1,52 @@
+---
+- name: Install etcd
+ yum: pkg=etcd state=present
+
+- name: Validate permissions on the config dir
+ file:
+ path: "{{ etcd_conf_dir }}"
+ state: directory
+ owner: etcd
+ group: etcd
+ mode: 0700
+
+- name: Validate permissions on certificate files
+ file:
+ path: "{{ item }}"
+ mode: 0600
+ group: etcd
+ owner: etcd
+ when: etcd_url_scheme == 'https'
+ with_items:
+ - "{{ etcd_ca_file }}"
+ - "{{ etcd_cert_file }}"
+ - "{{ etcd_key_file }}"
+
+- name: Validate permissions on peer certificate files
+ file:
+ path: "{{ item }}"
+ mode: 0600
+ group: etcd
+ owner: etcd
+ when: etcd_peer_url_scheme == 'https'
+ with_items:
+ - "{{ etcd_peer_ca_file }}"
+ - "{{ etcd_peer_cert_file }}"
+ - "{{ etcd_peer_key_file }}"
+
+- name: Write etcd global config file
+ template:
+ src: etcd.conf.j2
+ dest: /etc/etcd/etcd.conf
+ notify:
+ - restart etcd
+
+- name: Enable etcd
+ service:
+ name: etcd
+ state: started
+ enabled: yes
+ register: start_result
+
+- pause: seconds=30
+ when: start_result | changed
diff --git a/roles/etcd/templates/etcd.conf.j2 b/roles/etcd/templates/etcd.conf.j2
new file mode 100644
index 000000000..801be2c97
--- /dev/null
+++ b/roles/etcd/templates/etcd.conf.j2
@@ -0,0 +1,52 @@
+{% macro initial_cluster() -%}
+{% for host in groups[etcd_peers_group] -%}
+{% if loop.last -%}
+{{ host }}={{ etcd_peer_url_scheme }}://{{ hostvars[host]['ansible_' + etcd_interface]['ipv4']['address'] }}:{{ etcd_peer_port }}
+{%- else -%}
+{{ host }}={{ etcd_peer_url_scheme }}://{{ hostvars[host]['ansible_' + etcd_interface]['ipv4']['address'] }}:{{ etcd_peer_port }},
+{%- endif -%}
+{% endfor -%}
+{% endmacro -%}
+
+{% if groups[etcd_peers_group] and groups[etcd_peers_group] | length > 1 %}
+ETCD_NAME={{ inventory_hostname }}
+ETCD_LISTEN_PEER_URLS={{ etcd_listen_peer_urls }}
+{% else %}
+ETCD_NAME=default
+{% endif %}
+ETCD_DATA_DIR={{ etcd_data_dir }}
+#ETCD_SNAPSHOT_COUNTER="10000"
+#ETCD_HEARTBEAT_INTERVAL="100"
+#ETCD_ELECTION_TIMEOUT="1000"
+ETCD_LISTEN_CLIENT_URLS={{ etcd_listen_client_urls }}
+#ETCD_MAX_SNAPSHOTS="5"
+#ETCD_MAX_WALS="5"
+#ETCD_CORS=""
+
+{% if groups[etcd_peers_group] and groups[etcd_peers_group] | length > 1 %}
+#[cluster]
+ETCD_INITIAL_ADVERTISE_PEER_URLS={{ etcd_initial_advertise_peer_urls }}
+ETCD_INITIAL_CLUSTER={{ initial_cluster() }}
+ETCD_INITIAL_CLUSTER_STATE={{ etcd_initial_cluster_state }}
+ETCD_INITIAL_CLUSTER_TOKEN={{ etcd_initial_cluster_token }}
+#ETCD_DISCOVERY=""
+#ETCD_DISCOVERY_SRV=""
+#ETCD_DISCOVERY_FALLBACK="proxy"
+#ETCD_DISCOVERY_PROXY=""
+{% endif %}
+ETCD_ADVERTISE_CLIENT_URLS={{ etcd_advertise_client_urls }}
+
+#[proxy]
+#ETCD_PROXY="off"
+
+#[security]
+{% if etcd_url_scheme == 'https' -%}
+ETCD_CA_FILE={{ etcd_ca_file }}
+ETCD_CERT_FILE={{ etcd_cert_file }}
+ETCD_KEY_FILE={{ etcd_key_file }}
+{% endif -%}
+{% if etcd_peer_url_scheme == 'https' -%}
+ETCD_PEER_CA_FILE={{ etcd_peer_ca_file }}
+ETCD_PEER_CERT_FILE={{ etcd_peer_cert_file }}
+ETCD_PEER_KEY_FILE={{ etcd_peer_key_file }}
+{% endif -%}
diff --git a/roles/etcd_ca/README.md b/roles/etcd_ca/README.md
new file mode 100644
index 000000000..60a880e30
--- /dev/null
+++ b/roles/etcd_ca/README.md
@@ -0,0 +1,34 @@
+etcd_ca
+========================
+
+TODO
+
+Requirements
+------------
+
+TODO
+
+Role Variables
+--------------
+
+TODO
+
+Dependencies
+------------
+
+TODO
+
+Example Playbook
+----------------
+
+TODO
+
+License
+-------
+
+Apache License Version 2.0
+
+Author Information
+------------------
+
+Scott Dodson (sdodson@redhat.com)
diff --git a/roles/etcd_ca/meta/main.yml b/roles/etcd_ca/meta/main.yml
new file mode 100644
index 000000000..ce909b992
--- /dev/null
+++ b/roles/etcd_ca/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_facts }
diff --git a/roles/etcd_ca/tasks/main.yml b/roles/etcd_ca/tasks/main.yml
new file mode 100644
index 000000000..ab151fe5b
--- /dev/null
+++ b/roles/etcd_ca/tasks/main.yml
@@ -0,0 +1,44 @@
+---
+- file:
+ path: "{{ etcd_ca_dir }}/{{ item }}"
+ state: directory
+ mode: 0700
+ owner: root
+ group: root
+ with_items:
+ - certs
+ - crl
+ - fragments
+
+- command: cp /etc/pki/tls/openssl.cnf ./
+ args:
+ chdir: "{{ etcd_ca_dir }}/fragments"
+ creates: "{{ etcd_ca_dir }}/fragments/openssl.cnf"
+
+- template:
+ dest: "{{ etcd_ca_dir }}/fragments/openssl_append.cnf"
+ src: openssl_append.j2
+
+- assemble:
+ src: "{{ etcd_ca_dir }}/fragments"
+ dest: "{{ etcd_ca_dir }}/openssl.cnf"
+
+- command: touch index.txt
+ args:
+ chdir: "{{ etcd_ca_dir }}"
+ creates: "{{ etcd_ca_dir }}/index.txt"
+
+- copy:
+ dest: "{{ etcd_ca_dir }}/serial"
+ content: "01"
+ force: no
+
+- 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 }}
+ args:
+ chdir: "{{ etcd_ca_dir }}"
+ creates: "{{ etcd_ca_dir }}/ca.crt"
+ environment:
+ SAN: ''
diff --git a/roles/etcd_ca/templates/openssl_append.j2 b/roles/etcd_ca/templates/openssl_append.j2
new file mode 100644
index 000000000..de2adaead
--- /dev/null
+++ b/roles/etcd_ca/templates/openssl_append.j2
@@ -0,0 +1,51 @@
+
+[ etcd_v3_req ]
+basicConstraints = critical,CA:FALSE
+keyUsage = digitalSignature,keyEncipherment
+subjectAltName = ${ENV::SAN}
+
+[ etcd_ca ]
+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
+default_md = sha256
+preserve = no
+name_opt = ca_default
+cert_opt = ca_default
+policy = policy_anything
+unique_subject = no
+copy_extensions = copy
+
+[ etcd_v3_ca_self ]
+authorityKeyIdentifier = keyid,issuer
+basicConstraints = critical,CA:TRUE,pathlen:0
+keyUsage = critical,digitalSignature,keyEncipherment,keyCertSign
+subjectKeyIdentifier = hash
+
+[ etcd_v3_ca_peer ]
+authorityKeyIdentifier = keyid,issuer:always
+basicConstraints = critical,CA:FALSE
+extendedKeyUsage = clientAuth,serverAuth
+keyUsage = digitalSignature,keyEncipherment
+subjectKeyIdentifier = hash
+
+[ etcd_v3_ca_server ]
+authorityKeyIdentifier = keyid,issuer:always
+basicConstraints = critical,CA:FALSE
+extendedKeyUsage = serverAuth
+keyUsage = digitalSignature,keyEncipherment
+subjectKeyIdentifier = hash
+
+[ etcd_v3_ca_client ]
+authorityKeyIdentifier = keyid,issuer:always
+basicConstraints = critical,CA:FALSE
+extendedKeyUsage = clientAuth
+keyUsage = digitalSignature,keyEncipherment
+subjectKeyIdentifier = hash
diff --git a/roles/etcd_ca/vars/main.yml b/roles/etcd_ca/vars/main.yml
new file mode 100644
index 000000000..901e95027
--- /dev/null
+++ b/roles/etcd_ca/vars/main.yml
@@ -0,0 +1,3 @@
+---
+etcd_conf_dir: /etc/etcd
+etcd_ca_dir: /etc/etcd/ca
diff --git a/roles/etcd_certificates/README.md b/roles/etcd_certificates/README.md
new file mode 100644
index 000000000..95f8f8aab
--- /dev/null
+++ b/roles/etcd_certificates/README.md
@@ -0,0 +1,34 @@
+OpenShift etcd certificates
+========================
+
+TODO
+
+Requirements
+------------
+
+TODO
+
+Role Variables
+--------------
+
+TODO
+
+Dependencies
+------------
+
+TODO
+
+Example Playbook
+----------------
+
+TODO
+
+License
+-------
+
+Apache License Version 2.0
+
+Author Information
+------------------
+
+Scott Dodson (sdodson@redhat.com)
diff --git a/roles/etcd_certificates/meta/main.yml b/roles/etcd_certificates/meta/main.yml
new file mode 100644
index 000000000..41370fab4
--- /dev/null
+++ b/roles/etcd_certificates/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.8
+ platforms:
+ - name: EL
+ versions:
+ - 7
+ categories:
+ - cloud
+ - system
+dependencies:
+- { role: etcd_ca }
diff --git a/roles/etcd_certificates/tasks/client.yml b/roles/etcd_certificates/tasks/client.yml
new file mode 100644
index 000000000..28f33f442
--- /dev/null
+++ b/roles/etcd_certificates/tasks/client.yml
@@ -0,0 +1,42 @@
+---
+- name: Ensure generated_certs directory present
+ file:
+ path: "{{ etcd_generated_certs_dir }}/{{ item.etcd_cert_subdir }}"
+ state: directory
+ mode: 0700
+ with_items: etcd_needing_client_certs
+
+- name: Create the client csr
+ command: >
+ openssl req -new -keyout {{ item.etcd_cert_prefix }}client.key
+ -config {{ etcd_openssl_conf }}
+ -out {{ item.etcd_cert_prefix }}client.csr
+ -reqexts {{ etcd_req_ext }} -batch -nodes
+ -subj /CN={{ item.openshift.common.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 }}"
+ with_items: etcd_needing_client_certs
+
+- name: Sign and create the client crt
+ command: >
+ openssl ca -name {{ etcd_ca_name }} -config {{ etcd_openssl_conf }}
+ -out {{ item.etcd_cert_prefix }}client.crt
+ -in {{ item.etcd_cert_prefix }}client.csr
+ -batch
+ args:
+ chdir: "{{ etcd_generated_certs_dir }}/{{ item.etcd_cert_subdir }}"
+ creates: "{{ etcd_generated_certs_dir ~ '/' ~ item.etcd_cert_subdir ~ '/'
+ ~ item.etcd_cert_prefix ~ 'client.crt' }}"
+ environment:
+ SAN: ''
+ with_items: etcd_needing_client_certs
+
+- file:
+ src: "{{ etcd_ca_cert }}"
+ dest: "{{ etcd_generated_certs_dir}}/{{ item.etcd_cert_subdir }}/{{ item.etcd_cert_prefix }}ca.crt"
+ state: hard
+ with_items: etcd_needing_client_certs
diff --git a/roles/etcd_certificates/tasks/main.yml b/roles/etcd_certificates/tasks/main.yml
new file mode 100644
index 000000000..da875e8ea
--- /dev/null
+++ b/roles/etcd_certificates/tasks/main.yml
@@ -0,0 +1,9 @@
+---
+- include: client.yml
+ when: etcd_needing_client_certs is defined and etcd_needing_client_certs
+
+- include: server.yml
+ when: etcd_needing_server_certs is defined and etcd_needing_server_certs
+
+
+
diff --git a/roles/etcd_certificates/tasks/server.yml b/roles/etcd_certificates/tasks/server.yml
new file mode 100644
index 000000000..727b7fa2c
--- /dev/null
+++ b/roles/etcd_certificates/tasks/server.yml
@@ -0,0 +1,73 @@
+---
+- name: Ensure generated_certs directory present
+ file:
+ path: "{{ etcd_generated_certs_dir }}/{{ item.etcd_cert_subdir }}"
+ state: directory
+ mode: 0700
+ with_items: etcd_needing_server_certs
+
+- name: Create the server csr
+ command: >
+ openssl req -new -keyout {{ item.etcd_cert_prefix }}server.key
+ -config {{ etcd_openssl_conf }}
+ -out {{ item.etcd_cert_prefix }}server.csr
+ -reqexts {{ etcd_req_ext }} -batch -nodes
+ -subj /CN={{ item.openshift.common.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:{{ item.openshift.common.ip }}"
+ with_items: etcd_needing_server_certs
+
+- name: Sign and create the server crt
+ command: >
+ openssl ca -name {{ etcd_ca_name }} -config {{ etcd_openssl_conf }}
+ -out {{ item.etcd_cert_prefix }}server.crt
+ -in {{ item.etcd_cert_prefix }}server.csr
+ -extensions {{ etcd_ca_exts_server }} -batch
+ args:
+ chdir: "{{ etcd_generated_certs_dir }}/{{ item.etcd_cert_subdir }}"
+ creates: "{{ etcd_generated_certs_dir ~ '/' ~ item.etcd_cert_subdir ~ '/'
+ ~ item.etcd_cert_prefix ~ 'server.crt' }}"
+ environment:
+ SAN: ''
+ with_items: etcd_needing_server_certs
+
+- name: Create the peer csr
+ command: >
+ openssl req -new -keyout {{ item.etcd_cert_prefix }}peer.key
+ -config {{ etcd_openssl_conf }}
+ -out {{ item.etcd_cert_prefix }}peer.csr
+ -reqexts {{ etcd_req_ext }} -batch -nodes
+ -subj /CN={{ item.openshift.common.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:{{ item.openshift.common.ip }}"
+ with_items: etcd_needing_server_certs
+
+- name: Sign and create the peer crt
+ command: >
+ openssl ca -name {{ etcd_ca_name }} -config {{ etcd_openssl_conf }}
+ -out {{ item.etcd_cert_prefix }}peer.crt
+ -in {{ item.etcd_cert_prefix }}peer.csr
+ -extensions {{ etcd_ca_exts_peer }} -batch
+ args:
+ chdir: "{{ etcd_generated_certs_dir }}/{{ item.etcd_cert_subdir }}"
+ creates: "{{ etcd_generated_certs_dir ~ '/' ~ item.etcd_cert_subdir ~ '/'
+ ~ item.etcd_cert_prefix ~ 'peer.crt' }}"
+ environment:
+ SAN: ''
+ with_items: etcd_needing_server_certs
+
+- file:
+ src: "{{ etcd_ca_cert }}"
+ dest: "{{ etcd_generated_certs_dir}}/{{ item.etcd_cert_subdir }}/{{ item.etcd_cert_prefix }}ca.crt"
+ state: hard
+ with_items: etcd_needing_server_certs
+
+
diff --git a/roles/etcd_certificates/vars/main.yml b/roles/etcd_certificates/vars/main.yml
new file mode 100644
index 000000000..0eaeeb82b
--- /dev/null
+++ b/roles/etcd_certificates/vars/main.yml
@@ -0,0 +1,11 @@
+---
+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
diff --git a/roles/openshift_facts/library/openshift_facts.py b/roles/openshift_facts/library/openshift_facts.py
index ca5ea1da0..aff822a23 100755
--- a/roles/openshift_facts/library/openshift_facts.py
+++ b/roles/openshift_facts/library/openshift_facts.py
@@ -366,13 +366,23 @@ def set_url_facts_if_unset(facts):
console_port = facts['master']['console_port']
console_path = facts['master']['console_path']
etcd_use_ssl = facts['master']['etcd_use_ssl']
+ etcd_hosts = facts['master']['etcd_hosts']
etcd_port = facts['master']['etcd_port'],
hostname = facts['common']['hostname']
public_hostname = facts['common']['public_hostname']
if 'etcd_urls' not in facts['master']:
- facts['master']['etcd_urls'] = [format_url(etcd_use_ssl, hostname,
- etcd_port)]
+ etcd_urls = []
+ if etcd_hosts != '':
+ facts['master']['etcd_port'] = etcd_port
+ facts['master']['embedded_etcd'] = False
+ for host in etcd_hosts:
+ etcd_urls.append(format_url(etcd_use_ssl, host,
+ etcd_port))
+ else:
+ etcd_urls = [format_url(etcd_use_ssl, hostname,
+ etcd_port)]
+ facts['master']['etcd_urls'] = etcd_urls
if 'api_url' not in facts['master']:
facts['master']['api_url'] = format_url(api_use_ssl, hostname,
api_port)
@@ -695,7 +705,7 @@ class OpenShiftFacts(object):
if 'master' in roles:
master = dict(api_use_ssl=True, api_port='8443',
console_use_ssl=True, console_path='/console',
- console_port='8443', etcd_use_ssl=True,
+ console_port='8443', etcd_use_ssl=True, etcd_hosts='',
etcd_port='4001', portal_net='172.30.0.0/16',
embedded_etcd=True, embedded_kube=True,
embedded_dns=True, dns_port='53',
@@ -707,11 +717,7 @@ class OpenShiftFacts(object):
defaults['master'] = master
if 'node' in roles:
- node = dict(pod_cidr='', labels={}, annotations={}, portal_net='172.30.0.0/16')
- node['resources_cpu'] = self.system_facts['processor_cores']
- node['resources_memory'] = int(
- int(self.system_facts['memtotal_mb']) * 1024 * 1024 * 0.75
- )
+ node = dict(labels={}, annotations={}, portal_net='172.30.0.0/16')
defaults['node'] = node
return defaults
diff --git a/roles/openshift_master/tasks/main.yml b/roles/openshift_master/tasks/main.yml
index da0a663ec..02905f32d 100644
--- a/roles/openshift_master/tasks/main.yml
+++ b/roles/openshift_master/tasks/main.yml
@@ -12,11 +12,6 @@
yum: pkg=openshift-master state=present
register: install_result
-# TODO: Is this necessary or was this a workaround for an old bug in packaging?
-- name: Reload systemd units
- command: systemctl daemon-reload
- when: install_result | changed
-
- name: Set master OpenShift facts
openshift_facts:
role: master
@@ -31,6 +26,7 @@
console_url: "{{ openshift_master_console_url | default(None) }}"
console_use_ssl: "{{ openshift_master_console_use_ssl | default(None) }}"
public_console_url: "{{ openshift_master_public_console_url | default(None) }}"
+ etcd_hosts: "{{ openshift_master_etcd_hosts | default(None)}}"
etcd_port: "{{ openshift_master_etcd_port | default(None) }}"
etcd_use_ssl: "{{ openshift_master_etcd_use_ssl | default(None) }}"
etcd_urls: "{{ openshift_master_etcd_urls | default(None) }}"
@@ -65,16 +61,6 @@
path: "{{ openshift_master_config_dir }}"
state: directory
-- name: Create the master certificates if they do not already exist
- command: >
- {{ openshift.common.admin_binary }} create-master-certs
- --hostnames={{ openshift.common.hostname }},{{ openshift.common.public_hostname }}
- --master={{ openshift.master.api_url }}
- --public-master={{ openshift.master.public_api_url }}
- --cert-dir={{ openshift_master_config_dir }} --overwrite=false
- args:
- creates: "{{ openshift_master_config_dir }}/master.server.key"
-
- name: Create the policy file if it does not already exist
command: >
{{ openshift.common.admin_binary }} create-bootstrap-policy-file
@@ -128,6 +114,11 @@
- name: Start and enable openshift-master
service: name=openshift-master enabled=yes state=started
+ register: start_result
+
+- name: pause to prevent service restart from interfering with bootstrapping
+ pause: seconds=30
+ when: start_result | changed
- name: Create the OpenShift client config dir(s)
file:
diff --git a/roles/openshift_master/templates/master.yaml.v1.j2 b/roles/openshift_master/templates/master.yaml.v1.j2
index 3b8b18c39..bc766ec9b 100644
--- a/roles/openshift_master/templates/master.yaml.v1.j2
+++ b/roles/openshift_master/templates/master.yaml.v1.j2
@@ -18,19 +18,19 @@ corsAllowedOrigins:
{% for origin in ['127.0.0.1', 'localhost', openshift.common.hostname, openshift.common.ip, openshift.common.public_hostname, openshift.common.public_ip] %}
- {{ origin }}
{% endfor %}
-{% if openshift.master.embedded_dns %}
+{% if openshift.master.embedded_dns | bool %}
dnsConfig:
bindAddress: {{ openshift.master.bind_addr }}:{{ openshift.master.dns_port }}
{% endif %}
etcdClientInfo:
- ca: ca.crt
+ ca: {{ "ca.crt" if (openshift.master.embedded_etcd | bool) else "master.etcd-ca.crt" }}
certFile: master.etcd-client.crt
keyFile: master.etcd-client.key
urls:
{% for etcd_url in openshift.master.etcd_urls %}
- {{ etcd_url }}
{% endfor %}
-{% if openshift.master.embedded_etcd %}
+{% if openshift.master.embedded_etcd | bool %}
etcdConfig:
address: {{ openshift.common.hostname }}:{{ openshift.master.etcd_port }}
peerAddress: {{ openshift.common.hostname }}:7001
@@ -61,7 +61,7 @@ kubeletClientInfo:
certFile: master.kubelet-client.crt
keyFile: master.kubelet-client.key
port: 10250
-{% if openshift.master.embedded_kube %}
+{% if openshift.master.embedded_kube | bool %}
kubernetesMasterConfig:
apiLevels:
- v1beta3
diff --git a/roles/openshift_master_ca/README.md b/roles/openshift_master_ca/README.md
new file mode 100644
index 000000000..5b2d3601b
--- /dev/null
+++ b/roles/openshift_master_ca/README.md
@@ -0,0 +1,34 @@
+OpenShift Master CA
+========================
+
+TODO
+
+Requirements
+------------
+
+TODO
+
+Role Variables
+--------------
+
+TODO
+
+Dependencies
+------------
+
+TODO
+
+Example Playbook
+----------------
+
+TODO
+
+License
+-------
+
+Apache License Version 2.0
+
+Author Information
+------------------
+
+Jason DeTiberus (jdetiber@redhat.com)
diff --git a/roles/openshift_register_nodes/meta/main.yml b/roles/openshift_master_ca/meta/main.yml
index e40a152c1..f3236e850 100644
--- a/roles/openshift_register_nodes/meta/main.yml
+++ b/roles/openshift_master_ca/meta/main.yml
@@ -14,4 +14,3 @@ galaxy_info:
- system
dependencies:
- { role: openshift_facts }
-
diff --git a/roles/openshift_master_ca/tasks/main.yml b/roles/openshift_master_ca/tasks/main.yml
new file mode 100644
index 000000000..8163ecd7f
--- /dev/null
+++ b/roles/openshift_master_ca/tasks/main.yml
@@ -0,0 +1,22 @@
+---
+- name: Install the OpenShift package for admin tooling
+ yum: pkg=openshift state=present
+ register: install_result
+
+- name: Reload generated facts
+ openshift_facts:
+
+- name: Create openshift_master_config_dir if it doesn't exist
+ file:
+ path: "{{ openshift_master_config_dir }}"
+ state: directory
+
+- name: Create the master certificates if they do not already exist
+ command: >
+ {{ openshift.common.admin_binary }} create-master-certs
+ --hostnames={{ openshift.common.hostname }},{{ openshift.common.public_hostname }}
+ --master={{ openshift.master.api_url }}
+ --public-master={{ openshift.master.public_api_url }}
+ --cert-dir={{ openshift_master_config_dir }} --overwrite=false
+ args:
+ creates: "{{ openshift_master_config_dir }}/master.server.key"
diff --git a/roles/openshift_master_ca/vars/main.yml b/roles/openshift_master_ca/vars/main.yml
new file mode 100644
index 000000000..2925680bb
--- /dev/null
+++ b/roles/openshift_master_ca/vars/main.yml
@@ -0,0 +1,5 @@
+---
+openshift_master_config_dir: /etc/openshift/master
+openshift_master_ca_cert: "{{ openshift_master_config_dir }}/ca.crt"
+openshift_master_ca_key: "{{ openshift_master_config_dir }}/ca.key"
+openshift_master_ca_serial: "{{ openshift_master_config_dir }}/ca.serial.txt"
diff --git a/roles/openshift_master_certificates/README.md b/roles/openshift_master_certificates/README.md
new file mode 100644
index 000000000..ba3d5f28c
--- /dev/null
+++ b/roles/openshift_master_certificates/README.md
@@ -0,0 +1,34 @@
+OpenShift Master Certificates
+========================
+
+TODO
+
+Requirements
+------------
+
+TODO
+
+Role Variables
+--------------
+
+TODO
+
+Dependencies
+------------
+
+TODO
+
+Example Playbook
+----------------
+
+TODO
+
+License
+-------
+
+Apache License Version 2.0
+
+Author Information
+------------------
+
+Jason DeTiberus (jdetiber@redhat.com)
diff --git a/roles/openshift_master_certificates/meta/main.yml b/roles/openshift_master_certificates/meta/main.yml
new file mode 100644
index 000000000..fd7b73b0f
--- /dev/null
+++ b/roles/openshift_master_certificates/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.8
+ platforms:
+ - name: EL
+ versions:
+ - 7
+ categories:
+ - cloud
+ - system
+dependencies:
+- { role: openshift_master_ca }
diff --git a/roles/openshift_master_certificates/tasks/main.yml b/roles/openshift_master_certificates/tasks/main.yml
new file mode 100644
index 000000000..b5a3f8e40
--- /dev/null
+++ b/roles/openshift_master_certificates/tasks/main.yml
@@ -0,0 +1,24 @@
+---
+- name: Ensure the generated_configs directory present
+ file:
+ path: "{{ openshift_generated_configs_dir }}/{{ item.master_cert_subdir }}"
+ state: directory
+ mode: 0700
+ with_items: masters_needing_certs
+
+- file:
+ src: "{{ openshift_master_ca_cert }}"
+ dest: "{{ openshift_generated_configs_dir }}/{{ item.master_cert_subdir }}/ca.crt"
+ with_items: masters_needing_certs
+
+- name: Create the master certificates if they do not already exist
+ command: >
+ {{ openshift.common.admin_binary }} create-master-certs
+ --hostnames={{ item.openshift.common.hostname }},{{ item.openshift.common.public_hostname }}
+ --master={{ item.openshift.master.api_url }}
+ --public-master={{ item.openshift.master.public_api_url }}
+ --cert-dir={{ openshift_generated_configs_dir }}/{{ item.master_cert_subdir }}
+ --overwrite=false
+ args:
+ creates: "{{ openshift_generated_configs_dir }}/{{ item.master_cert_subdir }}/master.server.crt"
+ with_items: masters_needing_certs
diff --git a/roles/openshift_register_nodes/vars/main.yml b/roles/openshift_master_certificates/vars/main.yml
index 3801b8427..6e577b13b 100644
--- a/roles/openshift_register_nodes/vars/main.yml
+++ b/roles/openshift_master_certificates/vars/main.yml
@@ -1,8 +1,6 @@
---
-openshift_node_config_dir: /etc/openshift/node
-openshift_master_config_dir: /etc/openshift/master
openshift_generated_configs_dir: /etc/openshift/generated-configs
+openshift_master_config_dir: /etc/openshift/master
openshift_master_ca_cert: "{{ openshift_master_config_dir }}/ca.crt"
openshift_master_ca_key: "{{ openshift_master_config_dir }}/ca.key"
openshift_master_ca_serial: "{{ openshift_master_config_dir }}/ca.serial.txt"
-openshift_kube_api_version: v1beta3
diff --git a/roles/openshift_node/tasks/main.yml b/roles/openshift_node/tasks/main.yml
index 770b55351..e18846db8 100644
--- a/roles/openshift_node/tasks/main.yml
+++ b/roles/openshift_node/tasks/main.yml
@@ -1,5 +1,11 @@
---
# TODO: allow for overriding default ports where possible
+- fail:
+ msg: This role requres that osn_cluster_dns_domain is set
+ when: osn_cluster_dns_domain is not defined or not osn_cluster_dns_domain
+- fail:
+ msg: This role requres that osn_cluster_dns_ip is set
+ when: osn_cluster_dns_ip is not defined or not osn_cluster_dns_ip
- name: Install OpenShift Node package
yum: pkg=openshift-node state=present
@@ -10,11 +16,6 @@
register: sdn_install_result
when: openshift.common.use_openshift_sdn
-- name: Reload systemd units
- command: systemctl daemon-reload
- when: (node_install_result | changed or (openshift.common.use_openshift_sdn
- and sdn_install_result | changed))
-
- name: Set node OpenShift facts
openshift_facts:
role: "{{ item.role }}"
@@ -27,9 +28,6 @@
deployment_type: "{{ openshift_deployment_type }}"
- role: node
local_facts:
- resources_cpu: "{{ openshift_node_resources_cpu | default(none) }}"
- resources_memory: "{{ openshift_node_resources_memory | default(none) }}"
- pod_cidr: "{{ openshift_node_pod_cidr | default(none) }}"
labels: "{{ openshift_node_labels | default(none) }}"
annotations: "{{ openshift_node_annotations | default(none) }}"
registry_url: "{{ oreg_url | default(none) }}"
diff --git a/roles/openshift_node/templates/node.yaml.v1.j2 b/roles/openshift_node/templates/node.yaml.v1.j2
index f313f6a4b..7778a2a61 100644
--- a/roles/openshift_node/templates/node.yaml.v1.j2
+++ b/roles/openshift_node/templates/node.yaml.v1.j2
@@ -1,7 +1,7 @@
allowDisabledDocker: false
apiVersion: v1
-dnsDomain: {{ hostvars[openshift_first_master].openshift.dns.domain }}
-dnsIP: {{ hostvars[openshift_first_master].openshift.dns.ip }}
+dnsDomain: {{ osn_cluster_dns_domain }}
+dnsIP: {{ osn_cluster_dns_ip }}
dockerConfig:
execHandlerName: ""
imageConfig:
diff --git a/roles/openshift_node_certificates/tasks/main.yml b/roles/openshift_node_certificates/tasks/main.yml
index 949afc5eb..64a799dfb 100644
--- a/roles/openshift_node_certificates/tasks/main.yml
+++ b/roles/openshift_node_certificates/tasks/main.yml
@@ -3,6 +3,7 @@
file:
path: "{{ openshift_generated_configs_dir }}"
state: directory
+ when: nodes_needing_certs | length > 0
- name: Generate the node client config
command: >
diff --git a/roles/openshift_node_certificates/vars/main.yml b/roles/openshift_node_certificates/vars/main.yml
index 3801b8427..a018bb0f9 100644
--- a/roles/openshift_node_certificates/vars/main.yml
+++ b/roles/openshift_node_certificates/vars/main.yml
@@ -5,4 +5,3 @@ openshift_generated_configs_dir: /etc/openshift/generated-configs
openshift_master_ca_cert: "{{ openshift_master_config_dir }}/ca.crt"
openshift_master_ca_key: "{{ openshift_master_config_dir }}/ca.key"
openshift_master_ca_serial: "{{ openshift_master_config_dir }}/ca.serial.txt"
-openshift_kube_api_version: v1beta3
diff --git a/roles/openshift_register_nodes/README.md b/roles/openshift_register_nodes/README.md
deleted file mode 100644
index b1d2000f1..000000000
--- a/roles/openshift_register_nodes/README.md
+++ /dev/null
@@ -1,15 +0,0 @@
-OpenShift Register Nodes
-========================
-
-DEPRECATED!!!
-Nodes should now auto register themselves. Use openshift_node_certificates role instead.
-
-License
--------
-
-Apache License Version 2.0
-
-Author Information
-------------------
-
-Jason DeTiberus (jdetiber@redhat.com)
diff --git a/roles/openshift_register_nodes/library/kubernetes_register_node.py b/roles/openshift_register_nodes/library/kubernetes_register_node.py
deleted file mode 100755
index a8c38627b..000000000
--- a/roles/openshift_register_nodes/library/kubernetes_register_node.py
+++ /dev/null
@@ -1,513 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-# vim: expandtab:tabstop=4:shiftwidth=4
-#
-# disable pylint checks
-# permanently disabled unless someone wants to refactor the object model:
-# too-few-public-methods
-# no-self-use
-# too-many-arguments
-# too-many-locals
-# too-many-branches
-# pylint:disable=too-many-arguments, no-self-use
-# pylint:disable=too-many-locals, too-many-branches, too-few-public-methods
-"""Ansible module to register a kubernetes node to the cluster"""
-
-import os
-
-DOCUMENTATION = '''
----
-module: kubernetes_register_node
-short_description: Registers a kubernetes node with a master
-description:
- - Registers a kubernetes node with a master
-options:
- name:
- default: null
- description:
- - Identifier for this node (usually the node fqdn).
- required: true
- api_verison:
- choices: ['v1beta1', 'v1beta3']
- default: 'v1beta1'
- description:
- - Kubernetes API version to use
- required: true
- host_ip:
- default: null
- description:
- - IP Address to associate with the node when registering.
- Available in the following API versions: v1beta1.
- required: false
- cpu:
- default: null
- description:
- - Number of CPUs to allocate for this node. When using the v1beta1
- API, you must specify the CPU count as a floating point number
- with no more than 3 decimal places. API version v1beta3 and newer
- accepts arbitrary float values.
- required: false
- memory:
- default: null
- description:
- - Memory available for this node. When using the v1beta1 API, you
- must specify the memory size in bytes. API version v1beta3 and
- newer accepts binary SI and decimal SI values.
- required: false
-'''
-EXAMPLES = '''
-# Minimal node registration
-- openshift_register_node: name=ose3.node.example.com
-
-# Node registration using the v1beta1 API and assigning 1 CPU core and 10 GB of
-# Memory
-- openshift_register_node:
- name: ose3.node.example.com
- api_version: v1beta1
- hostIP: 192.168.1.1
- cpu: 1
- memory: 500000000
-'''
-
-
-class ClientConfigException(Exception):
- """Client Configuration Exception"""
- pass
-
-class ClientConfig(object):
- """ Representation of a client config
-
- Attributes:
- config (dict): dictionary representing the client configuration
-
- Args:
- client_opts (list of str): client options to use
- module (AnsibleModule):
-
- Raises:
- ClientConfigException:
- """
- def __init__(self, client_opts, module):
- kubectl = module.params['kubectl_cmd']
- _, output, _ = module.run_command((kubectl +
- ["config", "view", "-o", "json"] +
- client_opts), check_rc=True)
- self.config = json.loads(output)
-
- if not (bool(self.config['clusters']) or
- bool(self.config['contexts']) or
- bool(self.config['current-context']) or
- bool(self.config['users'])):
- raise ClientConfigException(
- "Client config missing required values: %s" % output
- )
-
- def current_context(self):
- """ Gets the current context for the client config
-
- Returns:
- str: The current context as set in the config
- """
- return self.config['current-context']
-
- def section_has_value(self, section_name, value):
- """ Test if specified section contains a value
-
- Args:
- section_name (str): config section to test
- value (str): value to test if present
- Returns:
- bool: True if successful, false otherwise
- """
- section = self.config[section_name]
- if isinstance(section, dict):
- return value in section
- else:
- val = next((item for item in section
- if item['name'] == value), None)
- return val is not None
-
- def has_context(self, context):
- """ Test if specified context exists in config
-
- Args:
- context (str): value to test if present
- Returns:
- bool: True if successful, false otherwise
- """
- return self.section_has_value('contexts', context)
-
- def has_user(self, user):
- """ Test if specified user exists in config
-
- Args:
- context (str): value to test if present
- Returns:
- bool: True if successful, false otherwise
- """
- return self.section_has_value('users', user)
-
- def has_cluster(self, cluster):
- """ Test if specified cluster exists in config
-
- Args:
- context (str): value to test if present
- Returns:
- bool: True if successful, false otherwise
- """
- return self.section_has_value('clusters', cluster)
-
- def get_value_for_context(self, context, attribute):
- """ Get the value of attribute in context
-
- Args:
- context (str): context to search
- attribute (str): attribute wanted
- Returns:
- str: The value for attribute in context
- """
- contexts = self.config['contexts']
- if isinstance(contexts, dict):
- return contexts[context][attribute]
- else:
- return next((c['context'][attribute] for c in contexts
- if c['name'] == context), None)
-
- def get_user_for_context(self, context):
- """ Get the user attribute in context
-
- Args:
- context (str): context to search
- Returns:
- str: The value for the attribute in context
- """
- return self.get_value_for_context(context, 'user')
-
- def get_cluster_for_context(self, context):
- """ Get the cluster attribute in context
-
- Args:
- context (str): context to search
- Returns:
- str: The value for the attribute in context
- """
- return self.get_value_for_context(context, 'cluster')
-
- def get_namespace_for_context(self, context):
- """ Get the namespace attribute in context
-
- Args:
- context (str): context to search
- Returns:
- str: The value for the attribute in context
- """
- return self.get_value_for_context(context, 'namespace')
-
-class Util(object):
- """Utility methods"""
- @staticmethod
- def remove_empty_elements(mapping):
- """ Recursively removes empty elements from a dict
-
- Args:
- mapping (dict): dict to remove empty attributes from
- Returns:
- dict: A copy of the dict with empty elements removed
- """
- if isinstance(mapping, dict):
- copy = mapping.copy()
- for key, val in mapping.iteritems():
- if not val:
- del copy[key]
- return copy
- else:
- return mapping
-
-class NodeResources(object):
- """ Kubernetes Node Resources
-
- Attributes:
- resources (dict): A dictionary representing the node resources
-
- Args:
- version (str): kubernetes api version
- cpu (str): string representation of the cpu resources for the node
- memory (str): string representation of the memory resources for the
- node
- """
- def __init__(self, version, cpu=None, memory=None):
- if version == 'v1beta1':
- self.resources = dict(capacity=dict())
- self.resources['capacity']['cpu'] = cpu
- self.resources['capacity']['memory'] = memory
-
- def get_resources(self):
- """ Get the dict representing the node resources
-
- Returns:
- dict: representation of the node resources with any empty
- elements removed
- """
- return Util.remove_empty_elements(self.resources)
-
-class NodeSpec(object):
- """ Kubernetes Node Spec
-
- Attributes:
- spec (dict): A dictionary representing the node resources
-
- Args:
- version (str): kubernetes api version
- cpu (str): string representation of the cpu resources for the node
- memory (str): string representation of the memory resources for the
- node
- cidr (str): string representation of the cidr block available for
- the node
- externalID (str): The external id of the node
- """
- def __init__(self, version, cpu=None, memory=None, cidr=None,
- externalID=None):
- if version == 'v1beta3':
- self.spec = dict(podCIDR=cidr, externalID=externalID,
- capacity=dict())
- self.spec['capacity']['cpu'] = cpu
- self.spec['capacity']['memory'] = memory
-
- def get_spec(self):
- """ Get the dict representing the node spec
-
- Returns:
- dict: representation of the node spec with any empty elements
- removed
- """
- return Util.remove_empty_elements(self.spec)
-
-class Node(object):
- """ Kubernetes Node
-
- Attributes:
- node (dict): A dictionary representing the node
-
- Args:
- module (AnsibleModule):
- client_opts (list): client connection options
- version (str, optional): kubernetes api version
- node_name (str, optional): name for node
- hostIP (str, optional): node host ip
- cpu (str, optional): cpu resources for the node
- memory (str, optional): memory resources for the node
- labels (list, optional): labels for the node
- annotations (list, optional): annotations for the node
- podCIDR (list, optional): cidr block to use for pods
- externalID (str, optional): external id of the node
- """
- def __init__(self, module, client_opts, version='v1beta1', node_name=None,
- hostIP=None, cpu=None, memory=None, labels=None,
- annotations=None, podCIDR=None, externalID=None):
- self.module = module
- self.client_opts = client_opts
- if version == 'v1beta1':
- self.node = dict(id=node_name,
- kind='Node',
- apiVersion=version,
- hostIP=hostIP,
- resources=NodeResources(version, cpu, memory),
- cidr=podCIDR,
- labels=labels,
- annotations=annotations,
- externalID=externalID)
- elif version == 'v1beta3':
- metadata = dict(name=node_name,
- labels=labels,
- annotations=annotations)
- self.node = dict(kind='Node',
- apiVersion=version,
- metadata=metadata,
- spec=NodeSpec(version, cpu, memory, podCIDR,
- externalID))
-
- def get_name(self):
- """ Get the name for the node
-
- Returns:
- str: node name
- """
- if self.node['apiVersion'] == 'v1beta1':
- return self.node['id']
- elif self.node['apiVersion'] == 'v1beta3':
- return self.node['metadata']['name']
-
- def get_node(self):
- """ Get the dict representing the node
-
- Returns:
- dict: representation of the node with any empty elements
- removed
- """
- node = self.node.copy()
- if self.node['apiVersion'] == 'v1beta1':
- node['resources'] = self.node['resources'].get_resources()
- elif self.node['apiVersion'] == 'v1beta3':
- node['spec'] = self.node['spec'].get_spec()
- return Util.remove_empty_elements(node)
-
- def exists(self):
- """ Tests if the node already exists
-
- Returns:
- bool: True if node exists, otherwise False
- """
- kubectl = self.module.params['kubectl_cmd']
- _, output, _ = self.module.run_command((kubectl + ["get", "nodes"] +
- self.client_opts),
- check_rc=True)
- if re.search(self.module.params['name'], output, re.MULTILINE):
- return True
- return False
-
- def create(self):
- """ Creates the node
-
- Returns:
- bool: True if node creation successful
- """
- kubectl = self.module.params['kubectl_cmd']
- cmd = kubectl + self.client_opts + ['create', '-f', '-']
- exit_code, output, error = self.module.run_command(
- cmd, data=self.module.jsonify(self.get_node())
- )
- if exit_code != 0:
- if re.search("minion \"%s\" already exists" % self.get_name(),
- error):
- self.module.exit_json(msg="node definition already exists",
- changed=False, node=self.get_node())
- else:
- self.module.fail_json(msg="Node creation failed.",
- exit_code=exit_code,
- output=output, error=error,
- node=self.get_node())
- else:
- return True
-
-def generate_client_opts(module):
- """ Generates the client options
-
- Args:
- module(AnsibleModule)
-
- Returns:
- str: client options
- """
- client_config = '~/.kube/.kubeconfig'
- if 'default_client_config' in module.params:
- client_config = module.params['default_client_config']
- user_has_client_config = os.path.exists(os.path.expanduser(client_config))
- if not (user_has_client_config or module.params['client_config']):
- module.fail_json(msg="Could not locate client configuration, "
- "client_config must be specified if "
- "~/.kube/.kubeconfig is not present")
-
- client_opts = []
- if module.params['client_config']:
- kubeconfig_flag = '--kubeconfig'
- if 'kubeconfig_flag' in module.params:
- kubeconfig_flag = module.params['kubeconfig_flag']
- client_opts.append(kubeconfig_flag + '=' + os.path.expanduser(module.params['client_config']))
-
- try:
- config = ClientConfig(client_opts, module)
- except ClientConfigException as ex:
- module.fail_json(msg="Failed to get client configuration",
- exception=str(ex))
-
- client_context = module.params['client_context']
- if config.has_context(client_context):
- if client_context != config.current_context():
- client_opts.append("--context=%s" % client_context)
- else:
- module.fail_json(msg="Context %s not found in client config" % client_context)
-
- client_user = module.params['client_user']
- if config.has_user(client_user):
- if client_user != config.get_user_for_context(client_context):
- client_opts.append("--user=%s" % client_user)
- else:
- module.fail_json(msg="User %s not found in client config" % client_user)
-
- client_cluster = module.params['client_cluster']
- if config.has_cluster(client_cluster):
- if client_cluster != config.get_cluster_for_context(client_context):
- client_opts.append("--cluster=%s" % client_cluster)
- else:
- module.fail_json(msg="Cluster %s not found in client config" % client_cluster)
-
- client_namespace = module.params['client_namespace']
- if client_namespace != config.get_namespace_for_context(client_context):
- client_opts.append("--namespace=%s" % client_namespace)
-
- return client_opts
-
-
-def main():
- """ main """
- module = AnsibleModule(
- argument_spec=dict(
- name=dict(required=True, type='str'),
- host_ip=dict(type='str'),
- api_version=dict(type='str', default='v1beta1',
- choices=['v1beta1', 'v1beta3']),
- cpu=dict(type='str'),
- memory=dict(type='str'),
- # TODO: needs documented
- labels=dict(type='dict', default={}),
- # TODO: needs documented
- annotations=dict(type='dict', default={}),
- # TODO: needs documented
- pod_cidr=dict(type='str'),
- # TODO: needs documented
- client_config=dict(type='str'),
- # TODO: needs documented
- client_cluster=dict(type='str', default='master'),
- # TODO: needs documented
- client_context=dict(type='str', default='default'),
- # TODO: needs documented
- client_namespace=dict(type='str', default='default'),
- # TODO: needs documented
- client_user=dict(type='str', default='system:admin'),
- # TODO: needs documented
- kubectl_cmd=dict(type='list', default=['kubectl']),
- # TODO: needs documented
- kubeconfig_flag=dict(type='str'),
- # TODO: needs documented
- default_client_config=dict(type='str')
- ),
- supports_check_mode=True
- )
-
- labels = module.params['labels']
- kube_hostname_label = 'kubernetes.io/hostname'
- if kube_hostname_label not in labels:
- labels[kube_hostname_label] = module.params['name']
-
- node = Node(module, generate_client_opts(module),
- module.params['api_version'], module.params['name'],
- module.params['host_ip'], module.params['cpu'],
- module.params['memory'], labels, module.params['annotations'],
- module.params['pod_cidr'])
-
- if node.exists():
- module.exit_json(changed=False, node=node.get_node())
- elif module.check_mode:
- module.exit_json(changed=True, node=node.get_node())
- elif node.create():
- module.exit_json(changed=True, msg="Node created successfully",
- node=node.get_node())
- else:
- module.fail_json(msg="Unknown error creating node", node=node.get_node())
-
-# ignore pylint errors related to the module_utils import
-# pylint: disable=redefined-builtin, unused-wildcard-import, wildcard-import
-# import module snippets
-from ansible.module_utils.basic import *
-if __name__ == '__main__':
- main()
diff --git a/roles/openshift_register_nodes/tasks/main.yml b/roles/openshift_register_nodes/tasks/main.yml
deleted file mode 100644
index 502dffc26..000000000
--- a/roles/openshift_register_nodes/tasks/main.yml
+++ /dev/null
@@ -1,53 +0,0 @@
----
-- name: Create openshift_generated_configs_dir if it doesn't exist
- file:
- path: "{{ openshift_generated_configs_dir }}"
- state: directory
-
-- name: Generate the node client config
- command: >
- {{ openshift.common.admin_binary }} create-api-client-config
- --certificate-authority={{ openshift_master_ca_cert }}
- --client-dir={{ openshift_generated_configs_dir }}/node-{{ item.openshift.common.hostname }}
- --groups=system:nodes
- --master={{ openshift.master.api_url }}
- --signer-cert={{ openshift_master_ca_cert }}
- --signer-key={{ openshift_master_ca_key }}
- --signer-serial={{ openshift_master_ca_serial }}
- --user=system:node:{{ item.openshift.common.hostname }}
- args:
- chdir: "{{ openshift_generated_configs_dir }}"
- creates: "{{ openshift_generated_configs_dir }}/node-{{ item.openshift.common.hostname }}"
- with_items: nodes_needing_certs
-
-- name: Generate the node server certificate
- delegate_to: "{{ openshift_first_master }}"
- command: >
- {{ openshift.common.admin_binary }} create-server-cert
- --cert=server.crt --key=server.key --overwrite=true
- --hostnames={{ [item.openshift.common.hostname, item.openshift.common.public_hostname]|unique|join(",") }}
- --signer-cert={{ openshift_master_ca_cert }}
- --signer-key={{ openshift_master_ca_key }}
- --signer-serial={{ openshift_master_ca_serial }}
- args:
- chdir: "{{ openshift_generated_configs_dir }}/node-{{ item.openshift.common.hostname }}"
- creates: "{{ openshift_generated_configs_dir }}/node-{{ item.openshift.common.hostname }}/server.crt"
- with_items: nodes_needing_certs
-
-- name: Register unregistered nodes
- kubernetes_register_node:
- kubectl_cmd: "{{ [openshift.common.client_binary] }}"
- default_client_config: '~/.kube/config'
- name: "{{ item.openshift.common.hostname }}"
- api_version: "{{ openshift_kube_api_version }}"
- cpu: "{{ item.openshift.node.resources_cpu | default(None) }}"
- memory: "{{ item.openshift.node.resources_memory | default(None) }}"
- pod_cidr: "{{ item.openshift.node.pod_cidr | default(None) }}"
- host_ip: "{{ item.openshift.common.ip }}"
- labels: "{{ item.openshift.node.labels | default({}) }}"
- annotations: "{{ item.openshift.node.annotations | default({}) }}"
- client_context: default/ose3-master-example-com:8443/system:openshift-master
- client_user: system:openshift-master/ose3-master-example-com:8443
- client_cluster: ose3-master-example-com:8443
- with_items: openshift_nodes
- register: register_result