From 4ac07696f3db92d1361290c3a0d7b7637d3d1994 Mon Sep 17 00:00:00 2001
From: Andrew Butcher <abutcher@redhat.com>
Date: Mon, 11 Apr 2016 15:45:26 -0400
Subject: Add support for creating secure router.

* Move openshift_router to openshift_hosted role which will eventually
  contain registry, metrics and logging.
* Adds option for specifying an openshift_hosted_router_certificate
  cert and key pair.
* Removes dependency on node label variables and retrieves the node
  list from the API s.t. this role can be applied to any cluster with
  existing nodes. I've added an openshift_hosted playbook that occurs
  after node install to account for this.
* Infrastructure nodes are selected using
  openshift_hosted_router_selector which is based on deployment type
  by default; openshift-enterprise -> "region=infra" and online ->
  "type=infra".
---
 roles/openshift_facts/library/openshift_facts.py | 70 +++++++++++++++---------
 roles/openshift_hosted/README.md                 | 55 +++++++++++++++++++
 roles/openshift_hosted/handlers/main.yml         |  0
 roles/openshift_hosted/meta/main.yml             | 16 ++++++
 roles/openshift_hosted/tasks/main.yml            |  3 +
 roles/openshift_hosted/tasks/router.yml          | 64 ++++++++++++++++++++++
 roles/openshift_hosted/vars/main.yml             |  2 +
 roles/openshift_router/README.md                 | 35 ------------
 roles/openshift_router/handlers/main.yml         |  0
 roles/openshift_router/meta/main.yml             | 15 -----
 roles/openshift_router/tasks/main.yml            | 10 ----
 roles/openshift_router/vars/main.yml             |  4 --
 12 files changed, 183 insertions(+), 91 deletions(-)
 create mode 100644 roles/openshift_hosted/README.md
 create mode 100644 roles/openshift_hosted/handlers/main.yml
 create mode 100644 roles/openshift_hosted/meta/main.yml
 create mode 100644 roles/openshift_hosted/tasks/main.yml
 create mode 100644 roles/openshift_hosted/tasks/router.yml
 create mode 100644 roles/openshift_hosted/vars/main.yml
 delete mode 100644 roles/openshift_router/README.md
 delete mode 100644 roles/openshift_router/handlers/main.yml
 delete mode 100644 roles/openshift_router/meta/main.yml
 delete mode 100644 roles/openshift_router/tasks/main.yml
 delete mode 100644 roles/openshift_router/vars/main.yml

(limited to 'roles')

diff --git a/roles/openshift_facts/library/openshift_facts.py b/roles/openshift_facts/library/openshift_facts.py
index 32e608e86..92d650550 100755
--- a/roles/openshift_facts/library/openshift_facts.py
+++ b/roles/openshift_facts/library/openshift_facts.py
@@ -63,7 +63,16 @@ def migrate_local_facts(facts):
     migrated_facts = copy.deepcopy(facts)
     return migrate_docker_facts(migrated_facts)
 
-
+def migrate_hosted_facts(facts):
+    """ Apply migrations for master facts """
+    if 'master' in facts:
+        if 'router_selector' in facts['master']:
+            if 'hosted' not in facts:
+                facts['hosted'] = {}
+            if 'router' not in facts['hosted']:
+                facts['hosted']['router'] = {}
+            facts['hosted']['router']['selector'] = facts['master'].pop('router_selector')
+    return facts
 
 def first_ip(network):
     """ Return the first IPv4 address in network
@@ -394,7 +403,7 @@ def set_node_schedulability(facts):
                 facts['node']['schedulable'] = True
     return facts
 
-def set_master_selectors(facts):
+def set_selectors(facts):
     """ Set selectors facts if not already present in facts dict
         Args:
             facts (dict): existing facts
@@ -403,16 +412,21 @@ def set_master_selectors(facts):
             facts if they were not already present
 
     """
+    deployment_type = facts['common']['deployment_type']
+    if deployment_type == 'online':
+        selector = "type=infra"
+    else:
+        selector = "region=infra"
+
+    if 'hosted' not in facts:
+        facts['hosted'] = {}
+    if 'router' not in facts['hosted']:
+        facts['hosted']['router'] = {}
+    if 'selector' not in facts['hosted']['router'] or facts['hosted']['router']['selector'] in [None, 'None']:
+        facts['hosted']['router']['selector'] = selector
+
     if 'master' in facts:
         if 'infra_nodes' in facts['master']:
-            deployment_type = facts['common']['deployment_type']
-            if deployment_type == 'online':
-                selector = "type=infra"
-            else:
-                selector = "region=infra"
-
-            if 'router_selector' not in facts['master']:
-                facts['master']['router_selector'] = selector
             if 'registry_selector' not in facts['master']:
                 facts['master']['registry_selector'] = selector
     return facts
@@ -1479,7 +1493,7 @@ class OpenShiftFacts(object):
         facts = set_flannel_facts_if_unset(facts)
         facts = set_nuage_facts_if_unset(facts)
         facts = set_node_schedulability(facts)
-        facts = set_master_selectors(facts)
+        facts = set_selectors(facts)
         facts = set_metrics_facts_if_unset(facts)
         facts = set_identity_providers_if_unset(facts)
         facts = set_sdn_facts_if_unset(facts, self.system_facts)
@@ -1573,23 +1587,25 @@ class OpenShiftFacts(object):
         if 'cloudprovider' in roles:
             defaults['cloudprovider'] = dict(kind=None)
 
-        defaults['hosted'] = dict(
-            registry=dict(
-                storage=dict(
-                    kind=None,
-                    volume=dict(
-                        name='registry',
-                        size='5Gi'
-                    ),
-                    nfs=dict(
-                        directory='/exports',
-                        options='*(rw,root_squash)'),
-                    host=None,
-                    access_modes=['ReadWriteMany'],
-                    create_pv=True
-                )
+        if 'hosted' in roles or self.role == 'hosted':
+            defaults['hosted'] = dict(
+                registry=dict(
+                    storage=dict(
+                        kind=None,
+                        volume=dict(
+                            name='registry',
+                            size='5Gi'
+                        ),
+                        nfs=dict(
+                            directory='/exports',
+                            options='*(rw,root_squash)'),
+                        host=None,
+                        access_modes=['ReadWriteMany'],
+                        create_pv=True
+                    )
+                ),
+                router=dict()
             )
-        )
 
         return defaults
 
diff --git a/roles/openshift_hosted/README.md b/roles/openshift_hosted/README.md
new file mode 100644
index 000000000..633ec0937
--- /dev/null
+++ b/roles/openshift_hosted/README.md
@@ -0,0 +1,55 @@
+OpenShift Hosted
+================
+
+OpenShift Hosted Resources
+
+* OpenShift Router
+
+Requirements
+------------
+
+This role requires a running OpenShift cluster with nodes labeled to
+match the openshift_hosted_router_selector (default: region=infra).
+
+Role Variables
+--------------
+
+From this role:
+
+| Name                                | Default value                            | Description                                                                                                          |
+|-------------------------------------|------------------------------------------|----------------------------------------------------------------------------------------------------------------------|
+| openshift_hosted_router_certificate | None                                     | Dictionary containing "certfile" and "keyfile" keys with values containing paths to local certificate files.         |
+| openshift_hosted_router_registryurl | 'openshift3/ose-${component}:${version}' | The image to base the OpenShift router on.                                                                           |
+| openshift_hosted_router_replicas    | Number of nodes matching selector        | The number of replicas to configure.                                                                                 |
+| openshift_hosted_router_selector    | region=infra                             | Node selector used when creating router. The OpenShift router will only be deployed to nodes matching this selector. |
+
+Dependencies
+------------
+
+* openshift_common
+* openshift_hosted_facts
+
+Example Playbook
+----------------
+
+```
+- name: Create hosted resources
+  hosts: oo_first_master
+  roles:
+  - role: openshift_hosted
+    openshift_hosted_router_certificate:
+      certfile: /path/to/my-router.crt
+      keyfile: /path/to/my-router.key
+    openshift_hosted_router_registryurl: 'registry.access.redhat.com/openshift3/ose-haproxy-router:v3.0.2.0'
+    openshift_hosted_router_selector: 'type=infra'
+```
+
+License
+-------
+
+Apache License, Version 2.0
+
+Author Information
+------------------
+
+Red Hat openshift@redhat.com
diff --git a/roles/openshift_hosted/handlers/main.yml b/roles/openshift_hosted/handlers/main.yml
new file mode 100644
index 000000000..e69de29bb
diff --git a/roles/openshift_hosted/meta/main.yml b/roles/openshift_hosted/meta/main.yml
new file mode 100644
index 000000000..75dfc24c3
--- /dev/null
+++ b/roles/openshift_hosted/meta/main.yml
@@ -0,0 +1,16 @@
+---
+galaxy_info:
+  author: OpenShift Red Hat
+  description: OpenShift Embedded Router
+  company: Red Hat, Inc.
+  license: Apache License, Version 2.0
+  min_ansible_version: 1.9
+  platforms:
+  - name: EL
+    versions:
+    - 7
+  categories:
+  - cloud
+dependencies:
+- openshift_common
+- openshift_hosted_facts
diff --git a/roles/openshift_hosted/tasks/main.yml b/roles/openshift_hosted/tasks/main.yml
new file mode 100644
index 000000000..d42a4e365
--- /dev/null
+++ b/roles/openshift_hosted/tasks/main.yml
@@ -0,0 +1,3 @@
+---
+
+- include: router.yml
diff --git a/roles/openshift_hosted/tasks/router.yml b/roles/openshift_hosted/tasks/router.yml
new file mode 100644
index 000000000..6a36f74b2
--- /dev/null
+++ b/roles/openshift_hosted/tasks/router.yml
@@ -0,0 +1,64 @@
+---
+- fail:
+    msg: "Both 'certfile' and 'keyfile' keys must be specified when supplying the openshift_hosted_router_certificate variable."
+  when: openshift_hosted_router_certificate is defined and ('certfile' not in openshift_hosted_router_certificate or 'keyfile' not in openshift_hosted_router_certificate)
+
+- name: Read router certificate and key
+  slurp:
+    src: "{{ item }}"
+  register: openshift_router_certificate_output
+  with_items:
+  - "{{ openshift_hosted_router_certificate.certfile }}"
+  - "{{ openshift_hosted_router_certificate.keyfile }}"
+  delegate_to: localhost
+  when: openshift_hosted_router_certificate is defined
+
+- name: Persist certificate contents
+  openshift_facts:
+    role: hosted
+    openshift_env:
+      openshift_hosted_router_certificate_contents: "{% for certificate in openshift_router_certificate_output.results -%}{{ certificate.content | b64decode }}{% endfor -%}"
+  when: openshift_hosted_router_certificate is defined
+
+- name: Create PEM certificate
+  copy:
+    content: "{{ openshift.hosted.router.certificate.contents }}"
+    dest: "{{ openshift_master_config_dir }}/openshift-router.pem"
+    mode: 0600
+  when: openshift.hosted.router.certificate | default(None) != None
+
+- name: Retrieve list of openshift nodes
+  command: >
+    {{ openshift.common.client_binary }} --api-version='v1' -o json
+    get nodes -n default --config={{ openshift.common.config_base }}/master/admin.kubeconfig
+  register: openshift_hosted_router_nodes_json
+  when: openshift.hosted.router.replicas | default(None) == None
+
+- name: Collect nodes matching router selector
+  set_fact:
+    openshift_hosted_router_nodes: >
+      {{ (openshift_hosted_router_nodes_json.stdout|from_json)['items']
+         | oo_oc_nodes_matching_selector(openshift.hosted.router.selector) }}
+  when: openshift.hosted.router.replicas | default(None) == None
+
+- name: Create OpenShift router
+  command: >
+    {{ openshift.common.admin_binary }} router --create
+    {% if openshift.hosted.router.replicas | default(None) != None -%}
+    --replicas={{ openshift.hosted.router.replicas }}
+    {% else -%}
+    --replicas={{ openshift_hosted_router_nodes | length }}
+    {% endif %}
+    {% if openshift.hosted.router.certificate | default(None) != None -%}
+    --default-cert={{ openshift_master_config_dir }}/openshift-router.pem
+    {% endif -%}
+    --namespace=default
+    --service-account=router
+    --selector='{{ openshift.hosted.router.selector }}'
+    --credentials={{ openshift_master_config_dir }}/openshift-router.kubeconfig
+    {% if openshift.hosted.router.registryurl | default(None)!= None -%}
+    --images='{{ openshift.hosted.router.registryurl }}'
+    {% endif -%}
+  register: openshift_hosted_router_results
+  changed_when: "'service exists' not in openshift_hosted_router_results.stdout"
+  when: openshift.hosted.router.replicas | default(None) != None or (openshift_hosted_router_nodes is defined and openshift_hosted_router_nodes | length > 0)
diff --git a/roles/openshift_hosted/vars/main.yml b/roles/openshift_hosted/vars/main.yml
new file mode 100644
index 000000000..9967e26f4
--- /dev/null
+++ b/roles/openshift_hosted/vars/main.yml
@@ -0,0 +1,2 @@
+---
+openshift_master_config_dir: "{{ openshift.common.config_base }}/master"
diff --git a/roles/openshift_router/README.md b/roles/openshift_router/README.md
deleted file mode 100644
index d490e1038..000000000
--- a/roles/openshift_router/README.md
+++ /dev/null
@@ -1,35 +0,0 @@
-OpenShift Container Router
-==========================
-
-OpenShift Router service installation
-
-Requirements
-------------
-
-Running OpenShift cluster
-
-Role Variables
---------------
-
-From this role:
-| Name               | Default value                                         |                     |
-|--------------------|-------------------------------------------------------|---------------------|
-|                    |                                                       |                     |
-
-Dependencies
-------------
-
-Example Playbook
-----------------
-
-TODO
-
-License
--------
-
-Apache License, Version 2.0
-
-Author Information
-------------------
-
-Red Hat openshift@redhat.com
diff --git a/roles/openshift_router/handlers/main.yml b/roles/openshift_router/handlers/main.yml
deleted file mode 100644
index e69de29bb..000000000
diff --git a/roles/openshift_router/meta/main.yml b/roles/openshift_router/meta/main.yml
deleted file mode 100644
index c2b0777b5..000000000
--- a/roles/openshift_router/meta/main.yml
+++ /dev/null
@@ -1,15 +0,0 @@
----
-galaxy_info:
-  author: OpenShift Red Hat
-  description: OpenShift Embedded Router
-  company: Red Hat, Inc.
-  license: Apache License, Version 2.0
-  min_ansible_version: 1.9
-  platforms:
-  - name: EL
-    versions:
-    - 7
-  categories:
-  - cloud
-  dependencies:
-  - openshift_facts
diff --git a/roles/openshift_router/tasks/main.yml b/roles/openshift_router/tasks/main.yml
deleted file mode 100644
index 40365d04d..000000000
--- a/roles/openshift_router/tasks/main.yml
+++ /dev/null
@@ -1,10 +0,0 @@
----
-- name: Deploy OpenShift Router
-  command: >
-    {{ openshift.common.admin_binary }} router
-    --create --replicas={{ openshift.master.infra_nodes | length }}
-    --namespace=default
-    --service-account=router {{ ortr_selector }}
-    --credentials={{ openshift_master_config_dir }}/openshift-router.kubeconfig {{ ortr_images }}
-  register: ortr_results
-  changed_when: "'service exists' not in ortr_results.stdout"
diff --git a/roles/openshift_router/vars/main.yml b/roles/openshift_router/vars/main.yml
deleted file mode 100644
index bcac12068..000000000
--- a/roles/openshift_router/vars/main.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-openshift_master_config_dir: "{{ openshift.common.config_base }}/master"
-ortr_images: "--images='{{ openshift.master.registry_url }}'"
-ortr_selector: "--selector='{{ openshift.master.router_selector }}'"
-- 
cgit v1.2.3