Browse Source

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

Devan Goodwin 8 năm trước cách đây
mục cha
commit
03f31fdc58
77 tập tin đã thay đổi với 1078 bổ sung558 xóa
  1. 3 83
      filter_plugins/oo_filters.py
  2. 57 53
      inventory/byo/hosts.aep.example
  3. 58 53
      inventory/byo/hosts.origin.example
  4. 58 53
      inventory/byo/hosts.ose.example
  5. 4 0
      openshift-ansible.spec
  6. 1 1
      playbooks/adhoc/docker_loopback_to_lvm/ops-docker-loopback-to-direct-lvm.yml
  7. 1 2
      playbooks/aws/openshift-cluster/config.yml
  8. 3 15
      playbooks/common/openshift-cluster/openshift_hosted.yml
  9. 0 5
      playbooks/common/openshift-master/config.yml
  10. 2 2
      playbooks/common/openshift-node/config.yml
  11. 1 2
      playbooks/gce/openshift-cluster/config.yml
  12. 1 2
      playbooks/libvirt/openshift-cluster/config.yml
  13. 6 17
      playbooks/libvirt/openshift-cluster/templates/domain.xml
  14. 11 5
      playbooks/libvirt/openshift-cluster/templates/user-data
  15. 1 2
      playbooks/openstack/openshift-cluster/config.yml
  16. 5 0
      playbooks/openstack/openshift-cluster/dns.yml
  17. 30 0
      playbooks/openstack/openshift-cluster/files/heat_stack.yaml
  18. 4 4
      roles/etcd_certificates/tasks/client.yml
  19. 6 6
      roles/etcd_certificates/tasks/server.yml
  20. 1 0
      roles/kube_nfs_volumes/meta/main.yml
  21. 3 0
      roles/openshift_cli/tasks/main.yml
  22. 3 3
      roles/openshift_examples/files/examples/v1.2/infrastructure-templates/enterprise/logging-deployer.yaml
  23. 21 1
      roles/openshift_examples/files/examples/v1.2/quickstart-templates/cakephp-mysql.json
  24. 17 2
      roles/openshift_examples/files/examples/v1.2/quickstart-templates/cakephp.json
  25. 19 1
      roles/openshift_examples/files/examples/v1.2/quickstart-templates/dancer-mysql.json
  26. 16 1
      roles/openshift_examples/files/examples/v1.2/quickstart-templates/dancer.json
  27. 21 1
      roles/openshift_examples/files/examples/v1.2/quickstart-templates/django-postgresql.json
  28. 16 1
      roles/openshift_examples/files/examples/v1.2/quickstart-templates/django.json
  29. 19 1
      roles/openshift_examples/files/examples/v1.2/quickstart-templates/nodejs-mongodb.json
  30. 16 1
      roles/openshift_examples/files/examples/v1.2/quickstart-templates/nodejs.json
  31. 22 1
      roles/openshift_examples/files/examples/v1.2/quickstart-templates/rails-postgresql.json
  32. 21 1
      roles/openshift_examples/files/examples/v1.3/quickstart-templates/cakephp-mysql.json
  33. 17 2
      roles/openshift_examples/files/examples/v1.3/quickstart-templates/cakephp.json
  34. 19 1
      roles/openshift_examples/files/examples/v1.3/quickstart-templates/dancer-mysql.json
  35. 16 1
      roles/openshift_examples/files/examples/v1.3/quickstart-templates/dancer.json
  36. 21 1
      roles/openshift_examples/files/examples/v1.3/quickstart-templates/django-postgresql.json
  37. 16 1
      roles/openshift_examples/files/examples/v1.3/quickstart-templates/django.json
  38. 19 1
      roles/openshift_examples/files/examples/v1.3/quickstart-templates/nodejs-mongodb.json
  39. 16 1
      roles/openshift_examples/files/examples/v1.3/quickstart-templates/nodejs.json
  40. 22 1
      roles/openshift_examples/files/examples/v1.3/quickstart-templates/rails-postgresql.json
  41. 0 51
      roles/openshift_examples/tasks/main.yml
  42. 1 0
      roles/openshift_expand_partition/meta/main.yml
  43. 11 5
      roles/openshift_facts/library/openshift_facts.py
  44. 12 8
      roles/openshift_hosted/README.md
  45. 0 0
      roles/openshift_hosted/defaults/main.yml
  46. 23 2
      roles/openshift_hosted/meta/main.yml
  47. 20 1
      roles/openshift_hosted/tasks/main.yml
  48. 40 0
      roles/openshift_hosted/tasks/registry/registry.yml
  49. 114 0
      roles/openshift_hosted/tasks/registry/storage/object_storage.yml
  50. 3 9
      roles/openshift_registry/tasks/main.yml
  51. 12 0
      roles/openshift_hosted/tasks/registry/storage/s3.yml
  52. 0 65
      roles/openshift_hosted/tasks/router.yml
  53. 70 0
      roles/openshift_hosted/tasks/router/router.yml
  54. 72 0
      roles/openshift_hosted/templates/registry_config.j2
  55. 9 0
      roles/openshift_hosted/templates/registry_config_secret.j2
  56. 1 0
      roles/openshift_hosted/vars/main.yml
  57. 9 0
      roles/openshift_hosted_facts/tasks/main.yml
  58. 2 0
      roles/openshift_master/README.md
  59. 0 1
      roles/openshift_master_facts/tasks/main.yml
  60. 7 7
      roles/openshift_metrics/README.md
  61. 2 0
      roles/openshift_node/README.md
  62. 5 0
      roles/openshift_persistent_volumes/README.md
  63. 3 3
      roles/openshift_registry/meta/main.yml
  64. 47 0
      roles/openshift_projects/tasks/main.yml
  65. 2 0
      roles/openshift_projects/vars/main.yml
  66. 0 37
      roles/openshift_registry/README.md
  67. 0 0
      roles/openshift_registry/handlers/main.yml
  68. 0 4
      roles/openshift_registry/vars/main.yml
  69. 0 0
      roles/openshift_repos/files/origin/gpg_keys/openshift-ansible-CentOS-SIG-PaaS
  70. 4 5
      roles/openshift_repos/files/rhel-origin/repos/CentOS-OpenShift-Origin.repo
  71. 0 20
      roles/openshift_repos/tasks/centos_sig.yaml
  72. 0 4
      roles/openshift_repos/tasks/main.yaml
  73. 3 3
      roles/openshift_serviceaccounts/tasks/main.yml
  74. 1 0
      roles/openshift_storage_nfs/README.md
  75. 1 0
      roles/openshift_storage_nfs_lvm/meta/main.yml
  76. 1 1
      roles/rhel_subscribe/meta/main.yml
  77. 10 4
      utils/src/ooinstall/variants.py

+ 3 - 83
filter_plugins/oo_filters.py

@@ -340,85 +340,6 @@ class FilterModule(object):
         return [x for x in data if filter_attr in x and x[filter_attr]]
 
     @staticmethod
-    def oo_oc_nodes_matching_selector(nodes, selector):
-        """ Filters a list of nodes by selector.
-
-            Examples:
-                nodes = [{"kind": "Node", "metadata": {"name": "node1.example.com",
-                          "labels": {"kubernetes.io/hostname": "node1.example.com",
-                          "color": "green"}}},
-                         {"kind": "Node", "metadata": {"name": "node2.example.com",
-                          "labels": {"kubernetes.io/hostname": "node2.example.com",
-                          "color": "red"}}}]
-                selector = 'color=green'
-                returns = ['node1.example.com']
-
-                nodes = [{"kind": "Node", "metadata": {"name": "node1.example.com",
-                          "labels": {"kubernetes.io/hostname": "node1.example.com",
-                          "color": "green"}}},
-                         {"kind": "Node", "metadata": {"name": "node2.example.com",
-                          "labels": {"kubernetes.io/hostname": "node2.example.com",
-                          "color": "red"}}}]
-                selector = 'color=green,color=red'
-                returns = ['node1.example.com','node2.example.com']
-
-            Args:
-                nodes (list[dict]): list of node definitions
-                selector (str): "label=value" node selector to filter `nodes` by
-            Returns:
-                list[str]: nodes filtered by selector
-        """
-        if not isinstance(nodes, list):
-            raise errors.AnsibleFilterError("failed expects nodes to be a list, got {0}".format(type(nodes)))
-        if not isinstance(selector, basestring):
-            raise errors.AnsibleFilterError("failed expects selector to be a string")
-        if not re.match('.*=.*', selector):
-            raise errors.AnsibleFilterError("failed selector does not match \"label=value\" format")
-        node_lists = []
-        for node_selector in ''.join(selector.split()).split(','):
-            label = node_selector.split('=')[0]
-            value = node_selector.split('=')[1]
-            node_lists.append(FilterModule.oo_oc_nodes_with_label(nodes, label, value))
-        nodes = set(node_lists[0])
-        for node_list in node_lists[1:]:
-            nodes.intersection_update(node_list)
-        return list(nodes)
-
-    @staticmethod
-    def oo_oc_nodes_with_label(nodes, label, value):
-        """ Filters a list of nodes by label, value.
-
-            Examples:
-                nodes = [{"kind": "Node", "metadata": {"name": "node1.example.com",
-                          "labels": {"kubernetes.io/hostname": "node1.example.com",
-                          "color": "green"}}},
-                         {"kind": "Node", "metadata": {"name": "node2.example.com",
-                          "labels": {"kubernetes.io/hostname": "node2.example.com",
-                          "color": "red"}}}]
-                label = 'color'
-                value = 'green'
-                returns = ['node1.example.com']
-            Args:
-                nodes (list[dict]): list of node definitions
-                label (str): label to filter `nodes` by
-                value (str): value of `label` to filter `nodes` by
-            Returns:
-                list[str]: nodes filtered by selector
-        """
-        if not isinstance(nodes, list):
-            raise errors.AnsibleFilterError("failed expects nodes to be a list")
-        if not isinstance(label, basestring):
-            raise errors.AnsibleFilterError("failed expects label to be a string")
-        if not isinstance(value, basestring):
-            raise errors.AnsibleFilterError("failed expects value to be a string")
-        matching_nodes = []
-        for node in nodes:
-            if label in node['metadata']['labels']:
-                if node['metadata']['labels'][label] == value:
-                    matching_nodes.append(node['metadata']['name'])
-        return matching_nodes
-
-    @staticmethod
     def oo_nodes_with_label(nodes, label, value=None):
         """ Filters a list of nodes by label and value (if provided)
 
@@ -707,7 +628,8 @@ class FilterModule(object):
             if regex.match(key):
                 facts[key] = hostvars[key]
 
-        migrations = {'openshift_router_selector': 'openshift_hosted_router_selector'}
+        migrations = {'openshift_router_selector': 'openshift_hosted_router_selector',
+                      'openshift_registry_selector': 'openshift_hosted_registry_selector'}
         for old_fact, new_fact in migrations.iteritems():
             if old_fact in facts and new_fact not in facts:
                 facts[new_fact] = facts[old_fact]
@@ -771,7 +693,7 @@ class FilterModule(object):
                                         fsType=filesystem,
                                         volumeID=volume_id)))
                             persistent_volumes.append(persistent_volume)
-                        else:
+                        elif kind != 'object':
                             msg = "|failed invalid storage kind '{0}' for component '{1}'".format(
                                 kind,
                                 component)
@@ -921,7 +843,5 @@ class FilterModule(object):
             "oo_get_hosts_from_hostvars": self.oo_get_hosts_from_hostvars,
             "oo_image_tag_to_rpm_version": self.oo_image_tag_to_rpm_version,
             "oo_merge_dicts": self.oo_merge_dicts,
-            "oo_oc_nodes_matching_selector": self.oo_oc_nodes_matching_selector,
-            "oo_oc_nodes_with_label": self.oo_oc_nodes_with_label,
             "oo_merge_hostvars": self.oo_merge_hostvars,
         }

+ 57 - 53
inventory/byo/hosts.aep.example

@@ -164,6 +164,9 @@ openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true',
 #osm_mcs_labels_per_project=5
 #osm_uid_allocator_range='1000000000-1999999999/10000'
 
+# Configure additional projects
+#openshift_additional_projects={'my-project': {'default_node_selector': 'label=value'}}
+
 # Enable cockpit
 #osm_use_cockpit=true
 #
@@ -244,10 +247,15 @@ openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true',
 # based on the number of nodes matching the openshift router selector.
 #openshift_hosted_router_replicas=2
 #
+# Router force subdomain (optional)
+# A router path format to force on all routes used by this router
+# (will ignore the route host value)
+#openshift_hosted_router_force_subdomain='${name}-${namespace}.apps.example.com'
+#
 # Router certificate (optional)
 # Provide local certificate paths which will be configured as the
 # router's default certificate.
-#openshift_hosted_router_certificate={"certfile": "/path/to/router.crt", "keyfile": "/path/to/router.key"}
+#openshift_hosted_router_certificate={"certfile": "/path/to/router.crt", "keyfile": "/path/to/router.key", "cafile": "/path/to/router-ca.crt"}
 
 # Openshift Registry Options
 #
@@ -263,7 +271,54 @@ openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true',
 # Registry selector (optional)
 # Registry will only be created if nodes matching this label are present.
 # Default value: 'region=infra'
-#openshift_registry_selector='region=infra'
+#openshift_hosted_registry_selector='region=infra'
+#
+# Registry replicas (optional)
+# Unless specified, openshift-ansible will calculate the replica count
+# based on the number of nodes matching the openshift registry selector.
+#openshift_hosted_registry_replicas=2
+
+# Registry Storage Options
+#
+# NFS Host Group
+# An NFS volume will be created with path "nfs_directory/volume_name"
+# on the host within the [nfs] host group.  For example, the volume
+# path using these options would be "/exports/registry"
+#openshift_hosted_registry_storage_kind=nfs
+#openshift_hosted_registry_storage_access_modes=['ReadWriteMany']
+#openshift_hosted_registry_storage_nfs_directory=/exports
+#openshift_hosted_registry_storage_nfs_options='*(rw,root_squash)'
+#openshift_hosted_registry_storage_volume_name=registry
+#openshift_hosted_registry_storage_volume_size=10Gi
+#
+# External NFS Host
+# NFS volume must already exist with path "nfs_directory/_volume_name" on
+# the storage_host. For example, the remote volume path using these
+# options would be "nfs.example.com:/exports/registry"
+#openshift_hosted_registry_storage_kind=nfs
+#openshift_hosted_registry_storage_access_modes=['ReadWriteMany']
+#openshift_hosted_registry_storage_host=nfs.example.com
+#openshift_hosted_registry_storage_nfs_directory=/exports
+#openshift_hosted_registry_storage_volume_name=registry
+#openshift_hosted_registry_storage_volume_size=10Gi
+#
+# Openstack
+# Volume must already exist.
+#openshift_hosted_registry_storage_kind=openstack
+#openshift_hosted_registry_storage_access_modes=['ReadWriteOnce']
+#openshift_hosted_registry_storage_openstack_filesystem=ext4
+#openshift_hosted_registry_storage_openstack_volumeID=3a650b4f-c8c5-4e0a-8ca5-eaee11f16c57
+#openshift_hosted_registry_storage_volume_size=10Gi
+#
+# AWS S3
+# S3 bucket must already exist.
+#openshift_hosted_registry_storage_kind=object
+#openshift_hosted_registry_storage_provider=s3
+#openshift_hosted_registry_storage_s3_accesskey=aws_access_key_id
+#openshift_hosted_registry_storage_s3_secretkey=aws_secret_access_key
+#openshift_hosted_registry_storage_s3_bucket=bucket_name
+#openshift_hosted_registry_storage_s3_region=bucket_region
+#openshift_hosted_registry_storage_s3_chunksize=26214400
 
 # Configure the multi-tenant SDN plugin (default is 'redhat/openshift-ovs-subnet')
 # os_sdn_network_plugin_name='redhat/openshift-ovs-multitenant'
@@ -334,57 +389,6 @@ openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true',
 # Configure dnsIP in the node config
 #openshift_dns_ip=172.30.0.1
 
-# Persistent Storage Options
-#
-## Registry Storage Options
-##
-## Storage Kind
-## Specifies which storage kind will be used for the registry.
-## "nfs" and "openstack" are supported kinds at this time.
-##openshift_hosted_registry_storage_kind=nfs
-##
-## Persistent Volume Access Mode
-## When using the 'openstack' storage kind, this has to be 'ReadWriteOnce'
-##openshift_hosted_registry_storage_access_modes=['ReadWriteMany']
-##
-## Registry Volume Name
-## Specify the storage volume name. This directory will be created
-## within openshift_hosted_registry_storage_nfs_directory if
-## specifying an [nfs] group. Ex. /exports/registry
-## This variable must be supplied if using a pre-existing nfs server.
-##openshift_hosted_registry_storage_volume_name=registry
-##
-## NFS Specific Options
-##
-## Storage Host
-## This variable can be used to identify a pre-existing storage host
-## if a storage host group corresponding to the storage kind (such as
-## [nfs]) is not specified,
-##openshift_hosted_registry_storage_host=nfs.example.com
-##
-## NFS Export Options
-##openshift_hosted_registry_storage_nfs_options='*(rw,root_squash)'
-##
-## NFS Export Directory
-## Specify the root exports directory. This directory will be created
-## if specifying an [nfs] host group.
-## This variable must be supplied if using a pre-existing nfs server.
-##openshift_hosted_registry_storage_nfs_directory=/exports
-##
-## Openstack Specific Options
-##
-## Openstack Volume ID
-## Specify the identifier of the volume to use for the registry.
-## At this time, the volume has to be created manually by the administrator.
-##openshift_hosted_registry_storage_openstack_volumeID=3a650b4f-c8c5-4e0a-8ca5-eaee11f16c57
-##
-## Openstack Volume Size
-##openshift_hosted_registry_storage_volume_size=10Gi
-##
-## Openstack Volume Filesystem
-## Specify the filesystem that will be used when formatting the volume
-##openshift_hosted_registry_storage_openstack_filesystem=ext4
-
 # Configure node kubelet arguments
 #openshift_node_kubelet_args={'max-pods': ['110'], 'image-gc-high-threshold': ['90'], 'image-gc-low-threshold': ['80']}
 

+ 58 - 53
inventory/byo/hosts.origin.example

@@ -170,6 +170,9 @@ openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true',
 #osm_mcs_labels_per_project=5
 #osm_uid_allocator_range='1000000000-1999999999/10000'
 
+# Configure additional projects
+#openshift_additional_projects={'my-project': {'default_node_selector': 'label=value'}}
+
 # Enable cockpit
 #osm_use_cockpit=true
 #
@@ -250,10 +253,15 @@ openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true',
 # based on the number of nodes matching the openshift router selector.
 #openshift_hosted_router_replicas=2
 #
+# Router force subdomain (optional)
+# A router path format to force on all routes used by this router
+# (will ignore the route host value)
+#openshift_hosted_router_force_subdomain='${name}-${namespace}.apps.example.com'
+#
 # Router certificate (optional)
 # Provide local certificate paths which will be configured as the
 # router's default certificate.
-#openshift_hosted_router_certificate={"certfile": "/path/to/router.crt", "keyfile": "/path/to/router.key"}
+#openshift_hosted_router_certificate={"certfile": "/path/to/router.crt", "keyfile": "/path/to/router.key", "cafile": "/path/to/router-ca.crt"}
 
 # Openshift Registry Options
 #
@@ -269,7 +277,55 @@ openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true',
 # Registry selector (optional)
 # Registry will only be created if nodes matching this label are present.
 # Default value: 'region=infra'
-#openshift_registry_selector='region=infra'
+#openshift_hosted_registry_selector='region=infra'
+#
+# Registry replicas (optional)
+# Unless specified, openshift-ansible will calculate the replica count
+# based on the number of nodes matching the openshift registry selector.
+#openshift_hosted_registry_replicas=2
+
+# Registry Storage Options
+#
+# NFS Host Group
+# An NFS volume will be created with path "nfs_directory/volume_name"
+# on the host within the [nfs] host group.  For example, the volume
+# path using these options would be "/exports/registry"
+#openshift_hosted_registry_storage_kind=nfs
+#openshift_hosted_registry_storage_access_modes=['ReadWriteMany']
+#openshift_hosted_registry_storage_nfs_directory=/exports
+#openshift_hosted_registry_storage_nfs_options='*(rw,root_squash)'
+#openshift_hosted_registry_storage_volume_name=registry
+#openshift_hosted_registry_storage_volume_size=10Gi
+#
+# External NFS Host
+# NFS volume must already exist with path "nfs_directory/_volume_name" on
+# the storage_host. For example, the remote volume path using these
+# options would be "nfs.example.com:/exports/registry"
+#openshift_hosted_registry_storage_kind=nfs
+#openshift_hosted_registry_storage_access_modes=['ReadWriteMany']
+#openshift_hosted_registry_storage_host=nfs.example.com
+#openshift_hosted_registry_storage_nfs_directory=/exports
+#openshift_hosted_registry_storage_volume_name=registry
+#openshift_hosted_registry_storage_volume_size=10Gi
+#
+# Openstack
+# Volume must already exist.
+#openshift_hosted_registry_storage_kind=openstack
+#openshift_hosted_registry_storage_access_modes=['ReadWriteOnce']
+#openshift_hosted_registry_storage_openstack_filesystem=ext4
+#openshift_hosted_registry_storage_openstack_volumeID=3a650b4f-c8c5-4e0a-8ca5-eaee11f16c57
+#openshift_hosted_registry_storage_volume_size=10Gi
+#
+# AWS S3
+# S3 bucket must already exist.
+#openshift_hosted_registry_storage_kind=object
+#openshift_hosted_registry_storage_provider=s3
+#openshift_hosted_registry_storage_s3_accesskey=aws_access_key_id
+#openshift_hosted_registry_storage_s3_secretkey=aws_secret_access_key
+#openshift_hosted_registry_storage_s3_bucket=bucket_name
+#openshift_hosted_registry_storage_s3_region=bucket_region
+#openshift_hosted_registry_storage_s3_chunksize=26214400
+#openshift_hosted_registry_pullthrough=true
 
 # Configure the multi-tenant SDN plugin (default is 'redhat/openshift-ovs-subnet')
 # os_sdn_network_plugin_name='redhat/openshift-ovs-multitenant'
@@ -340,57 +396,6 @@ openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true',
 # Configure dnsIP in the node config
 #openshift_dns_ip=172.30.0.1
 
-# Persistent Storage Options
-#
-## Registry Storage Options
-##
-## Storage Kind
-## Specifies which storage kind will be used for the registry.
-## "nfs" and "openstack" are supported kinds at this time.
-##openshift_hosted_registry_storage_kind=nfs
-##
-## Persistent Volume Access Mode
-## When using the 'openstack' storage kind, this has to be 'ReadWriteOnce'
-##openshift_hosted_registry_storage_access_modes=['ReadWriteMany']
-##
-## Registry Volume Name
-## Specify the storage volume name. This directory will be created
-## within openshift_hosted_registry_storage_nfs_directory if
-## specifying an [nfs] group. Ex. /exports/registry
-## This variable must be supplied if using a pre-existing nfs server.
-##openshift_hosted_registry_storage_volume_name=registry
-##
-## NFS Specific Options
-##
-## Storage Host
-## This variable can be used to identify a pre-existing storage host
-## if a storage host group corresponding to the storage kind (such as
-## [nfs]) is not specified,
-##openshift_hosted_registry_storage_host=nfs.example.com
-##
-## NFS Export Options
-##openshift_hosted_registry_storage_nfs_options='*(rw,root_squash)'
-##
-## NFS Export Directory
-## Specify the root exports directory. This directory will be created
-## if specifying an [nfs] host group.
-## This variable must be supplied if using a pre-existing nfs server.
-##openshift_hosted_registry_storage_nfs_directory=/exports
-##
-## Openstack Specific Options
-##
-## Openstack Volume ID
-## Specify the identifier of the volume to use for the registry.
-## At this time, the volume has to be created manually by the administrator.
-##openshift_hosted_registry_storage_openstack_volumeID=3a650b4f-c8c5-4e0a-8ca5-eaee11f16c57
-##
-## Openstack Volume Size
-##openshift_hosted_registry_storage_volume_size=10Gi
-##
-## Openstack Volume Filesystem
-## Specify the filesystem that will be used when formatting the volume
-##openshift_hosted_registry_storage_openstack_filesystem=ext4
-
 # Configure node kubelet arguments
 #openshift_node_kubelet_args={'max-pods': ['110'], 'image-gc-high-threshold': ['90'], 'image-gc-low-threshold': ['80']}
 

+ 58 - 53
inventory/byo/hosts.ose.example

@@ -164,6 +164,9 @@ openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true',
 #osm_mcs_labels_per_project=5
 #osm_uid_allocator_range='1000000000-1999999999/10000'
 
+# Configure additional projects
+#openshift_additional_projects={'my-project': {'default_node_selector': 'label=value'}}
+
 # Enable cockpit
 #osm_use_cockpit=true
 #
@@ -244,10 +247,15 @@ openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true',
 # based on the number of nodes matching the openshift router selector.
 #openshift_hosted_router_replicas=2
 #
+# Router force subdomain (optional)
+# A router path format to force on all routes used by this router
+# (will ignore the route host value)
+#openshift_hosted_router_force_subdomain='${name}-${namespace}.apps.example.com'
+#
 # Router certificate (optional)
 # Provide local certificate paths which will be configured as the
 # router's default certificate.
-#openshift_hosted_router_certificate={"certfile": "/path/to/router.crt", "keyfile": "/path/to/router.key"}
+#openshift_hosted_router_certificate={"certfile": "/path/to/router.crt", "keyfile": "/path/to/router.key", "cafile": "/path/to/router-ca.crt"}
 
 # Openshift Registry Options
 #
@@ -263,7 +271,55 @@ openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true',
 # Registry selector (optional)
 # Registry will only be created if nodes matching this label are present.
 # Default value: 'region=infra'
-#openshift_registry_selector='region=infra'
+#openshift_hosted_registry_selector='region=infra'
+#
+# Registry replicas (optional)
+# Unless specified, openshift-ansible will calculate the replica count
+# based on the number of nodes matching the openshift registry selector.
+#openshift_hosted_registry_replicas=2
+
+# Registry Storage Options
+#
+# NFS Host Group
+# An NFS volume will be created with path "nfs_directory/volume_name"
+# on the host within the [nfs] host group.  For example, the volume
+# path using these options would be "/exports/registry"
+#openshift_hosted_registry_storage_kind=nfs
+#openshift_hosted_registry_storage_access_modes=['ReadWriteMany']
+#openshift_hosted_registry_storage_nfs_directory=/exports
+#openshift_hosted_registry_storage_nfs_options='*(rw,root_squash)'
+#openshift_hosted_registry_storage_volume_name=registry
+#openshift_hosted_registry_storage_volume_size=10Gi
+#
+# External NFS Host
+# NFS volume must already exist with path "nfs_directory/_volume_name" on
+# the storage_host. For example, the remote volume path using these
+# options would be "nfs.example.com:/exports/registry"
+#openshift_hosted_registry_storage_kind=nfs
+#openshift_hosted_registry_storage_access_modes=['ReadWriteMany']
+#openshift_hosted_registry_storage_host=nfs.example.com
+#openshift_hosted_registry_storage_nfs_directory=/exports
+#openshift_hosted_registry_storage_volume_name=registry
+#openshift_hosted_registry_storage_volume_size=10Gi
+#
+# Openstack
+# Volume must already exist.
+#openshift_hosted_registry_storage_kind=openstack
+#openshift_hosted_registry_storage_access_modes=['ReadWriteOnce']
+#openshift_hosted_registry_storage_openstack_filesystem=ext4
+#openshift_hosted_registry_storage_openstack_volumeID=3a650b4f-c8c5-4e0a-8ca5-eaee11f16c57
+#openshift_hosted_registry_storage_volume_size=10Gi
+#
+# AWS S3
+# S3 bucket must already exist.
+#openshift_hosted_registry_storage_kind=object
+#openshift_hosted_registry_storage_provider=s3
+#openshift_hosted_registry_storage_s3_accesskey=aws_access_key_id
+#openshift_hosted_registry_storage_s3_secretkey=aws_secret_access_key
+#openshift_hosted_registry_storage_s3_bucket=bucket_name
+#openshift_hosted_registry_storage_s3_region=bucket_region
+#openshift_hosted_registry_storage_s3_chunksize=26214400
+#openshift_hosted_registry_pullthrough=true
 
 # Configure the multi-tenant SDN plugin (default is 'redhat/openshift-ovs-subnet')
 # os_sdn_network_plugin_name='redhat/openshift-ovs-multitenant'
@@ -334,57 +390,6 @@ openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true',
 # Configure dnsIP in the node config
 #openshift_dns_ip=172.30.0.1
 
-# Persistent Storage Options
-#
-## Registry Storage Options
-##
-## Storage Kind
-## Specifies which storage kind will be used for the registry.
-## "nfs" and "openstack" are supported kinds at this time.
-##openshift_hosted_registry_storage_kind=nfs
-##
-## Persistent Volume Access Mode
-## When using the 'openstack' storage kind, this has to be 'ReadWriteOnce'
-##openshift_hosted_registry_storage_access_modes=['ReadWriteMany']
-##
-## Registry Volume Name
-## Specify the storage volume name. This directory will be created
-## within openshift_hosted_registry_storage_nfs_directory if
-## specifying an [nfs] group. Ex. /exports/registry
-## This variable must be supplied if using a pre-existing nfs server.
-##openshift_hosted_registry_storage_volume_name=registry
-##
-## NFS Specific Options
-##
-## Storage Host
-## This variable can be used to identify a pre-existing storage host
-## if a storage host group corresponding to the storage kind (such as
-## [nfs]) is not specified,
-##openshift_hosted_registry_storage_host=nfs.example.com
-##
-## NFS Export Options
-##openshift_hosted_registry_storage_nfs_options='*(rw,root_squash)'
-##
-## NFS Export Directory
-## Specify the root exports directory. This directory will be created
-## if specifying an [nfs] host group.
-## This variable must be supplied if using a pre-existing nfs server.
-##openshift_hosted_registry_storage_nfs_directory=/exports
-##
-## Openstack Specific Options
-##
-## Openstack Volume ID
-## Specify the identifier of the volume to use for the registry.
-## At this time, the volume has to be created manually by the administrator.
-##openshift_hosted_registry_storage_openstack_volumeID=3a650b4f-c8c5-4e0a-8ca5-eaee11f16c57
-##
-## Openstack Volume Size
-##openshift_hosted_registry_storage_volume_size=10Gi
-##
-## Openstack Volume Filesystem
-## Specify the filesystem that will be used when formatting the volume
-##openshift_hosted_registry_storage_openstack_filesystem=ext4
-
 # Configure node kubelet arguments
 #openshift_node_kubelet_args={'max-pods': ['110'], 'image-gc-high-threshold': ['90'], 'image-gc-low-threshold': ['80']}
 

+ 4 - 0
openshift-ansible.spec

@@ -57,6 +57,10 @@ cp inventory/byo/* docs/example-inventories/
 # openshift-ansible-playbooks install
 cp -rp playbooks %{buildroot}%{_datadir}/ansible/%{name}/
 
+# BZ1330091
+find -L %{buildroot}%{_datadir}/ansible/%{name}/playbooks -name lookup_plugins -type l -delete
+find -L %{buildroot}%{_datadir}/ansible/%{name}/playbooks -name filter_plugins -type l -delete
+
 # openshift-ansible-roles install
 cp -rp roles %{buildroot}%{_datadir}/ansible/%{name}/
 

+ 1 - 1
playbooks/adhoc/docker_loopback_to_lvm/ops-docker-loopback-to-direct-lvm.yml

@@ -16,7 +16,7 @@
 #  * You may need to re-deploy docker images after this is run (like monitoring)
 
 - name: Fix docker to have a provisioned iops drive
-  hosts: "{{ cli_name }}"
+  hosts: "{{ cli_host }}"
   user: root
   connection: ssh
   gather_facts: no

+ 1 - 2
playbooks/aws/openshift-cluster/config.yml

@@ -23,9 +23,8 @@
     openshift_debug_level: "{{ debug_level }}"
     openshift_deployment_type: "{{ deployment_type }}"
     openshift_public_hostname: "{{ ec2_ip_address }}"
-    openshift_registry_selector: 'type=infra'
+    openshift_hosted_registry_selector: 'type=infra'
     openshift_hosted_router_selector: 'type=infra'
-    openshift_infra_nodes: "{{ g_infra_hosts }}"
     openshift_node_labels:
       region: "{{ deployment_vars[deployment_type].region }}"
       type: "{{ hostvars[inventory_hostname]['ec2_tag_sub-host-type'] if inventory_hostname in groups['tag_host-type_node'] else hostvars[inventory_hostname]['ec2_tag_host-type'] }}"

+ 3 - 15
playbooks/common/openshift-cluster/openshift_hosted.yml

@@ -1,30 +1,18 @@
-- name: Create persistent volumes and create hosted services
+- name: Create persistent volumes
   hosts: oo_first_master
   vars:
-    attach_registry_volume: "{{ openshift.hosted.registry.storage.kind != None }}"
-    deploy_infra: "{{ openshift.master.infra_nodes | default([]) | length > 0 }}"
     persistent_volumes: "{{ hostvars[groups.oo_first_master.0] | oo_persistent_volumes(groups) }}"
     persistent_volume_claims: "{{ hostvars[groups.oo_first_master.0] | oo_persistent_volume_claims }}"
   roles:
   - role: openshift_persistent_volumes
     when: persistent_volumes | length > 0 or persistent_volume_claims | length > 0
-  - role: openshift_serviceaccounts
-    openshift_serviceaccounts_names:
-    - router
-    - registry
-    openshift_serviceaccounts_namespace: default
-    openshift_serviceaccounts_sccs:
-    - privileged
-  - role: openshift_registry
-    registry_volume_claim: "{{ openshift.hosted.registry.storage.volume.name }}-claim"
-    when: deploy_infra | bool and attach_registry_volume | bool
-  - role: openshift_metrics
-    when: openshift.hosted.metrics.deploy | bool
 
 - name: Create Hosted Resources
   hosts: oo_first_master
   pre_tasks:
   - set_fact:
       openshift_hosted_router_registryurl: "{{ hostvars[groups.oo_first_master.0].openshift.master.registry_url }}"
+      openshift_hosted_registry_registryurl: "{{ hostvars[groups.oo_first_master.0].openshift.master.registry_url }}"
+    when: "'master' in hostvars[groups.oo_first_master.0].openshift and 'registry_url' in hostvars[groups.oo_first_master.0].openshift.master"
   roles:
   - role: openshift_hosted

+ 0 - 5
playbooks/common/openshift-master/config.yml

@@ -186,11 +186,6 @@
                                 | list ) }}"
       master_cert_subdir: master-{{ openshift.common.hostname }}
       master_cert_config_dir: "{{ openshift.common.config_base }}/master"
-  - set_fact:
-      openshift_infra_nodes: "{{ hostvars | oo_select_keys(groups['oo_nodes_to_config'])
-                                 | oo_nodes_with_label('region', 'infra')
-                                 | oo_collect('inventory_hostname') }}"
-    when: openshift_infra_nodes is not defined and groups.oo_nodes_to_config | default([]) | length > 0
 
 - name: Configure master certificates
   hosts: oo_first_master

+ 2 - 2
playbooks/common/openshift-node/config.yml

@@ -184,7 +184,7 @@
         -C {{ etcd_generated_certs_dir }}/{{ item.etcd_cert_subdir }} .
     args:
       creates: "{{ etcd_generated_certs_dir }}/{{ item.etcd_cert_subdir }}.tgz"
-    with_items: etcd_needing_client_certs | default([])
+    with_items: "{{ etcd_needing_client_certs | default([]) }}"
   - name: Retrieve the etcd cert tarballs
     fetch:
       src: "{{ etcd_generated_certs_dir }}/{{ item.etcd_cert_subdir }}.tgz"
@@ -192,7 +192,7 @@
       flat: yes
       fail_on_missing: yes
       validate_checksum: yes
-    with_items: etcd_needing_client_certs | default([])
+    with_items: "{{ etcd_needing_client_certs | default([]) }}"
 
 - name: Copy the external etcd flannel certs to the nodes
   hosts: oo_nodes_to_config

+ 1 - 2
playbooks/gce/openshift-cluster/config.yml

@@ -26,9 +26,8 @@
     openshift_debug_level: "{{ debug_level }}"
     openshift_deployment_type: "{{ deployment_type }}"
     openshift_hostname: "{{ gce_private_ip }}"
-    openshift_registry_selector: 'type=infra'
+    openshift_hosted_registry_selector: 'type=infra'
     openshift_hosted_router_selector: 'type=infra'
-    openshift_infra_nodes: "{{ g_infra_hosts }}"
     openshift_master_cluster_method: 'native'
     openshift_use_openshift_sdn: "{{ lookup('oo_option', 'use_openshift_sdn') }}"
     os_sdn_network_plugin_name: "{{ lookup('oo_option', 'sdn_network_plugin_name') }}"

+ 1 - 2
playbooks/libvirt/openshift-cluster/config.yml

@@ -26,9 +26,8 @@
     openshift_cluster_id: "{{ cluster_id }}"
     openshift_debug_level: "{{ debug_level }}"
     openshift_deployment_type: "{{ deployment_type }}"
-    openshift_registry_selector: 'type=infra'
+    openshift_hosted_registry_selector: 'type=infra'
     openshift_hosted_router_selector: 'type=infra'
-    openshift_infra_nodes: "{{ g_infra_hosts }}"
     openshift_master_cluster_method: 'native'
     openshift_use_openshift_sdn: "{{ lookup('oo_option', 'use_openshift_sdn') }}"
     os_sdn_network_plugin_name: "{{ lookup('oo_option', 'sdn_network_plugin_name') }}"

+ 6 - 17
playbooks/libvirt/openshift-cluster/templates/domain.xml

@@ -30,22 +30,22 @@
   <devices>
     <emulator>/usr/bin/qemu-system-x86_64</emulator>
     <disk type='file' device='disk'>
-      <driver name='qemu' type='qcow2'/>
+      <driver name='qemu' type='qcow2' discard='unmap'/>
       <source file='{{ libvirt_storage_pool_path }}/{{ item }}.qcow2'/>
-      <target dev='vda' bus='virtio'/>
+      <target dev='sda' bus='scsi'/>
     </disk>
     <disk type='file' device='disk'>
-      <driver name='qemu' type='qcow2'/>
+      <driver name='qemu' type='qcow2' discard='unmap'/>
       <source file='{{ libvirt_storage_pool_path }}/{{ item }}-docker.qcow2'/>
-      <target dev='vdb' bus='virtio'/>
+      <target dev='sdb' bus='scsi'/>
     </disk>
     <disk type='file' device='cdrom'>
       <driver name='qemu' type='raw'/>
       <source file='{{ libvirt_storage_pool_path }}/{{ item }}_cloud-init.iso'/>
-      <target dev='vdc' bus='virtio'/>
+      <target dev='sdc' bus='scsi'/>
       <readonly/>
     </disk>
-    <controller type='usb' index='0' />
+    <controller type='scsi' model='virtio-scsi' />
     <interface type='network'>
       <source network='{{ libvirt_network }}'/>
       <model type='virtio'/>
@@ -56,17 +56,6 @@
     <console type='pty'>
       <target type='serial' port='0'/>
     </console>
-    <channel type='spicevmc'>
-      <target type='virtio' name='com.redhat.spice.0'/>
-    </channel>
-    <input type='tablet' bus='usb' />
-    <input type='mouse' bus='ps2'/>
-    <graphics type='spice' autoport='yes' />
-    <video>
-      <model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1'/>
-    </video>
-    <redirdev bus='usb' type='spicevmc'>
-    </redirdev>
     <memballoon model='virtio'>
     </memballoon>
   </devices>

+ 11 - 5
playbooks/libvirt/openshift-cluster/templates/user-data

@@ -5,7 +5,7 @@ hostname: {{ item[0] }}
 fqdn: {{ item[0] }}.example.com
 
 mounts:
-- [ vdb ]
+- [ sdb ]
 
 users:
   - default
@@ -26,12 +26,18 @@ write_files:
     permissions: 440
     content: |
         Defaults:openshift !requiretty
-  - content: |
-      DEVS=/dev/vdb
-      VG=docker_vg
-    path: /etc/sysconfig/docker-storage-setup
+  - path: /etc/sysconfig/docker-storage-setup
     owner: root:root
     permissions: '0644'
+    content: |
+      DEVS=/dev/sdb
+      VG=docker_vg
+      EXTRA_DOCKER_STORAGE_OPTIONS='--storage-opt dm.blkdiscard=true'
+  - path: /etc/systemd/system/fstrim.timer.d/hourly.conf
+    content: |
+      [Timer]
+      OnCalendar=hourly
 
 runcmd:
   - NETWORK_CONFIG=/etc/sysconfig/network-scripts/ifcfg-eth0; if ! grep DHCP_HOSTNAME ${NETWORK_CONFIG}; then echo 'DHCP_HOSTNAME="{{ item[0] }}.example.com"' >> ${NETWORK_CONFIG}; fi; pkill -9 dhclient; service network restart
+  - systemctl enable --now fstrim.timer

+ 1 - 2
playbooks/openstack/openshift-cluster/config.yml

@@ -23,9 +23,8 @@
     openshift_cluster_id: "{{ cluster_id }}"
     openshift_debug_level: "{{ debug_level }}"
     openshift_deployment_type: "{{ deployment_type }}"
-    openshift_registry_selector: 'type=infra'
+    openshift_hosted_registry_selector: 'type=infra'
     openshift_hosted_router_selector: 'type=infra'
-    openshift_infra_nodes: "{{ g_infra_hosts }}"
     openshift_master_cluster_method: 'native'
     openshift_use_openshift_sdn: "{{ lookup('oo_option', 'use_openshift_sdn') }}"
     os_sdn_network_plugin_name: "{{ lookup('oo_option', 'sdn_network_plugin_name') }}"

+ 5 - 0
playbooks/openstack/openshift-cluster/dns.yml

@@ -35,6 +35,11 @@
   - vars.yml
   - cluster_hosts.yml
   roles:
+    # Explicitly calling openshift_facts because it appears that when
+    # rhel_subscribe is skipped that the openshift_facts dependency for
+    # openshift_repos is also skipped (this is the case at least for Ansible
+    # 2.0.2)
+    - openshift_facts
     - role: rhel_subscribe
       when: deployment_type in ["enterprise", "atomic-enterprise", "openshift-enterprise"] and
             ansible_distribution == "RedHat" and

+ 30 - 0
playbooks/openstack/openshift-cluster/files/heat_stack.yaml

@@ -280,6 +280,10 @@ resources:
           port_range_max: 8443
         - direction: ingress
           protocol: tcp
+          port_range_min: 8444
+          port_range_max: 8444
+        - direction: ingress
+          protocol: tcp
           port_range_min: 53
           port_range_max: 53
         - direction: ingress
@@ -302,6 +306,22 @@ resources:
           protocol: udp
           port_range_min: 24224
           port_range_max: 24224
+        - direction: ingress
+          protocol: tcp
+          port_range_min: 2224
+          port_range_max: 2224
+        - direction: ingress
+          protocol: udp
+          port_range_min: 5404
+          port_range_max: 5404
+        - direction: ingress
+          protocol: udp
+          port_range_min: 5405
+          port_range_max: 5405
+        - direction: ingress
+          protocol: tcp
+          port_range_min: 9090
+          port_range_max: 9090
 
   etcd-secgrp:
     type: OS::Neutron::SecurityGroup
@@ -359,6 +379,16 @@ resources:
           port_range_max: 10250
           remote_mode: remote_group_id
         - direction: ingress
+          protocol: tcp
+          port_range_min: 10255
+          port_range_max: 10255
+          remote_mode: remote_group_id
+        - direction: ingress
+          protocol: udp
+          port_range_min: 10255
+          port_range_max: 10255
+          remote_mode: remote_group_id
+        - direction: ingress
           protocol: udp
           port_range_min: 4789
           port_range_max: 4789

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

@@ -4,7 +4,7 @@
     path: "{{ etcd_generated_certs_dir }}/{{ item.etcd_cert_subdir }}"
     state: directory
     mode: 0700
-  with_items: etcd_needing_client_certs | default([])
+  with_items: "{{ etcd_needing_client_certs | default([]) }}"
 
 - name: Create the client csr
   command: >
@@ -19,7 +19,7 @@
                  ~ item.etcd_cert_prefix ~ 'client.csr' }}"
   environment:
     SAN: "IP:{{ item.etcd_ip }}"
-  with_items: etcd_needing_client_certs | default([])
+  with_items: "{{ etcd_needing_client_certs | default([]) }}"
 
 - name: Sign and create the client crt
   command: >
@@ -33,10 +33,10 @@
                  ~ item.etcd_cert_prefix ~ 'client.crt' }}"
   environment:
     SAN: "IP:{{ item.etcd_ip }}"
-  with_items: etcd_needing_client_certs | default([])
+  with_items: "{{ etcd_needing_client_certs | default([]) }}"
 
 - 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 | default([])
+  with_items: "{{ etcd_needing_client_certs | default([]) }}"

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

@@ -4,7 +4,7 @@
     path: "{{ etcd_generated_certs_dir }}/{{ item.etcd_cert_subdir }}"
     state: directory
     mode: 0700
-  with_items: etcd_needing_server_certs | default([])
+  with_items: "{{ etcd_needing_server_certs | default([]) }}"
 
 - name: Create the server csr
   command: >
@@ -19,7 +19,7 @@
                  ~ item.etcd_cert_prefix ~ 'server.csr' }}"
   environment:
     SAN: "IP:{{ item.etcd_ip }}"
-  with_items: etcd_needing_server_certs  | default([])
+  with_items: "{{ etcd_needing_server_certs  | default([]) }}"
 
 - name: Sign and create the server crt
   command: >
@@ -33,7 +33,7 @@
                  ~ item.etcd_cert_prefix ~ 'server.crt' }}"
   environment:
     SAN: "IP:{{ item.etcd_ip }}"
-  with_items: etcd_needing_server_certs  | default([])
+  with_items: "{{ etcd_needing_server_certs  | default([]) }}"
 
 - name: Create the peer csr
   command: >
@@ -48,7 +48,7 @@
                  ~ item.etcd_cert_prefix ~ 'peer.csr' }}"
   environment:
     SAN: "IP:{{ item.etcd_ip }}"
-  with_items: etcd_needing_server_certs | default([])
+  with_items: "{{ etcd_needing_server_certs | default([]) }}"
 
 - name: Sign and create the peer crt
   command: >
@@ -62,10 +62,10 @@
                  ~ item.etcd_cert_prefix ~ 'peer.crt' }}"
   environment:
     SAN: "IP:{{ item.etcd_ip }}"
-  with_items: etcd_needing_server_certs | default([])
+  with_items: "{{ etcd_needing_server_certs | default([]) }}"
 
 - 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 | default([])
+  with_items: "{{ etcd_needing_server_certs | default([]) }}"

+ 1 - 0
roles/kube_nfs_volumes/meta/main.yml

@@ -14,3 +14,4 @@ galaxy_info:
     - all
   categories:
     - cloud
+dependencies: []

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

@@ -29,3 +29,6 @@
 - name: Reload facts to pick up installed OpenShift version
   openshift_facts:
 
+- name: Install bash completion for oc tools
+  action: "{{ ansible_pkg_mgr }} name=bash-completion state=present"
+  when: not openshift.common.is_containerized | bool

+ 3 - 3
roles/openshift_examples/files/examples/v1.2/infrastructure-templates/enterprise/logging-deployer.yaml

@@ -82,13 +82,13 @@ objects:
         secretName: logging-deployer
 parameters:
 -
-  description: 'Specify image prefix for logging components; e.g. for "registry.access.redhat.com/openshift3/logging-deployment:3.2.0", set prefix "registry.access.redhat.com/openshift3/"'
+  description: 'Specify image prefix for logging components; e.g. for "registry.access.redhat.com/openshift3/logging-deployment:3.2.1", set prefix "registry.access.redhat.com/openshift3/"'
   name: IMAGE_PREFIX
   value: registry.access.redhat.com/openshift3/
 -
-  description: 'Specify version for logging components; e.g. for "registry.access.redhat.com/openshift3/logging-deployment:3.2.0", set version "3.2.0"'
+  description: 'Specify version for logging components; e.g. for "registry.access.redhat.com/openshift3/logging-deployment:3.2.1", set version "3.2.1"'
   name: IMAGE_VERSION
-  value: "3.2.0"
+  value: "3.2.1"
 -
   description: "If true, set up to use a second ES cluster for ops logs."
   name: ENABLE_OPS_CLUSTER

+ 21 - 1
roles/openshift_examples/files/examples/v1.2/quickstart-templates/cakephp-mysql.json

@@ -84,7 +84,13 @@
               "kind": "ImageStreamTag",
               "namespace": "${NAMESPACE}",
               "name": "php:5.6"
-            }
+            },
+            "env":  [
+              {
+                  "name": "COMPOSER_MIRROR",
+                  "value": "${COMPOSER_MIRROR}"
+              }
+            ]
           }
         },
         "output": {
@@ -376,24 +382,28 @@
       "name": "NAMESPACE",
       "displayName": "Namespace",
       "description": "The OpenShift Namespace where the ImageStream resides.",
+      "required": true,
       "value": "openshift"
     },
     {
       "name": "MEMORY_LIMIT",
       "displayName": "Memory Limit",
       "description": "Maximum amount of memory the CakePHP container can use.",
+      "required": true,
       "value": "512Mi"
     },
     {
       "name": "MEMORY_MYSQL_LIMIT",
       "displayName": "Memory Limit (MySQL)",
       "description": "Maximum amount of memory the MySQL container can use.",
+      "required": true,
       "value": "512Mi"
     },
     {
       "name": "SOURCE_REPOSITORY_URL",
       "displayName": "Git Repository URL",
       "description": "The URL of the repository with your application source code.",
+      "required": true,
       "value": "https://github.com/openshift/cakephp-ex.git"
     },
     {
@@ -422,22 +432,26 @@
     {
       "name": "DATABASE_SERVICE_NAME",
       "displayName": "Database Service Name",
+      "required": true,
       "value": "mysql"
     },
     {
       "name": "DATABASE_ENGINE",
       "displayName": "Database Engine",
       "description": "Database engine: postgresql, mysql or sqlite (default).",
+      "required": true,
       "value": "mysql"
     },
     {
       "name": "DATABASE_NAME",
       "displayName": "Database Name",
+      "required": true,
       "value": "default"
     },
     {
       "name": "DATABASE_USER",
       "displayName": "Database User",
+      "required": true,
       "value": "cakephp"
     },
     {
@@ -472,6 +486,12 @@
       "displayName": "OPcache Revalidation Frequency",
       "description": "How often to check script timestamps for updates, in seconds. 0 will result in OPcache checking for updates on every request.",
       "value": "2"
+    },
+    {
+      "name": "COMPOSER_MIRROR",
+      "displayName": "Custom Composer Mirror URL",
+      "description": "The custom Composer mirror URL",
+      "value": ""
     }
   ]
 }

+ 17 - 2
roles/openshift_examples/files/examples/v1.2/quickstart-templates/cakephp.json

@@ -31,7 +31,7 @@
           }
         ],
         "selector": {
-          "name": "${NAME}" 
+          "name": "${NAME}"
         }
       }
     },
@@ -84,7 +84,13 @@
               "kind": "ImageStreamTag",
               "namespace": "${NAMESPACE}",
               "name": "php:5.6"
-            }
+            },
+            "env":  [
+              {
+                  "name": "COMPOSER_MIRROR",
+                  "value": "${COMPOSER_MIRROR}"
+              }
+            ]
           }
         },
         "output": {
@@ -239,18 +245,21 @@
       "name": "NAMESPACE",
       "displayName": "Namespace",
       "description": "The OpenShift Namespace where the ImageStream resides.",
+      "required": true,
       "value": "openshift"
     },
     {
       "name": "MEMORY_LIMIT",
       "displayName": "Memory Limit",
       "description": "Maximum amount of memory the container can use.",
+      "required": true,
       "value": "512Mi"
     },
     {
       "name": "SOURCE_REPOSITORY_URL",
       "displayName": "Git Repository URL",
       "description": "The URL of the repository with your application source code.",
+      "required": true,
       "value": "https://github.com/openshift/cakephp-ex.git"
     },
     {
@@ -323,6 +332,12 @@
       "displayName": "OPcache Revalidation Frequency",
       "description": "How often to check script timestamps for updates, in seconds. 0 will result in OPcache checking for updates on every request.",
       "value": "2"
+    },
+    {
+      "name": "COMPOSER_MIRROR",
+      "displayName": "Custom Composer Mirror URL",
+      "description": "The custom Composer mirror URL",
+      "value": ""
     }
   ]
 }

+ 19 - 1
roles/openshift_examples/files/examples/v1.2/quickstart-templates/dancer-mysql.json

@@ -84,7 +84,13 @@
               "kind": "ImageStreamTag",
               "namespace": "${NAMESPACE}",
               "name": "perl:5.20"
-            }
+            },
+            "env":  [
+              {
+                  "name": "CPAN_MIRROR",
+                  "value": "${CPAN_MIRROR}"
+              }
+            ]
           }
         },
         "output": {
@@ -350,24 +356,28 @@
       "name": "NAMESPACE",
       "displayName": "Namespace",
       "description": "The OpenShift Namespace where the ImageStream resides.",
+      "required": true,
       "value": "openshift"
     },
     {
       "name": "MEMORY_LIMIT",
       "displayName": "Memory Limit",
       "description": "Maximum amount of memory the Perl Dancer container can use.",
+      "required": true,
       "value": "512Mi"
     },
     {
       "name": "MEMORY_MYSQL_LIMIT",
       "displayName": "Memory Limit (MySQL)",
       "description": "Maximum amount of memory the MySQL container can use.",
+      "required": true,
       "value": "512Mi"
     },
     {
       "name": "SOURCE_REPOSITORY_URL",
       "displayName": "Git Repository URL",
       "description": "The URL of the repository with your application source code.",
+      "required": true,
       "value": "https://github.com/openshift/dancer-ex.git"
     },
     {
@@ -408,6 +418,7 @@
     {
       "name": "DATABASE_SERVICE_NAME",
       "displayName": "Database Service Name",
+      "required": true,
       "value": "database"
     },
     {
@@ -425,6 +436,7 @@
     {
       "name": "DATABASE_NAME",
       "displayName": "Database Name",
+      "required": true,
       "value": "sampledb"
     },
     {
@@ -439,6 +451,12 @@
       "description": "Your secret key for verifying the integrity of signed cookies.",
       "generate": "expression",
       "from": "[a-z0-9]{127}"
+    },
+    {
+      "name": "CPAN_MIRROR",
+      "displayName": "Custom CPAN Mirror URL",
+      "description": "The custom CPAN mirror URL",
+      "value": ""
     }
   ]
 }

+ 16 - 1
roles/openshift_examples/files/examples/v1.2/quickstart-templates/dancer.json

@@ -84,7 +84,13 @@
               "kind": "ImageStreamTag",
               "namespace": "${NAMESPACE}",
               "name": "perl:5.20"
-            }
+            },
+            "env":  [
+              {
+                  "name": "CPAN_MIRROR",
+                  "value": "${CPAN_MIRROR}"
+              }
+            ]
           }
         },
         "output": {
@@ -207,18 +213,21 @@
       "name": "NAMESPACE",
       "displayName": "Namespace",
       "description": "The OpenShift Namespace where the ImageStream resides.",
+      "required": true,
       "value": "openshift"
     },
     {
       "name": "MEMORY_LIMIT",
       "displayName": "Memory Limit",
       "description": "Maximum amount of memory the container can use.",
+      "required": true,
       "value": "512Mi"
     },
     {
       "name": "SOURCE_REPOSITORY_URL",
       "displayName": "Git Repository URL",
       "description": "The URL of the repository with your application source code.",
+      "required": true,
       "value": "https://github.com/openshift/dancer-ex.git"
     },
     {
@@ -256,6 +265,12 @@
       "displayName": "Perl Module Reload",
       "description": "Set this to \"true\" to enable automatic reloading of modified Perl modules.",
       "value": ""
+    },
+    {
+      "name": "CPAN_MIRROR",
+      "displayName": "Custom CPAN Mirror URL",
+      "description": "The custom CPAN mirror URL",
+      "value": ""
     }
   ]
 }

+ 21 - 1
roles/openshift_examples/files/examples/v1.2/quickstart-templates/django-postgresql.json

@@ -84,7 +84,13 @@
               "kind": "ImageStreamTag",
               "namespace": "${NAMESPACE}",
               "name": "python:3.4"
-            }
+            },
+            "env": [
+              {
+                  "name": "PIP_INDEX_URL",
+                  "value": "${PIP_INDEX_URL}"
+              }
+            ]
           }
         },
         "output": {
@@ -359,24 +365,28 @@
     {
       "name": "NAMESPACE",
       "displayName": "Namespace",
+      "required": true,
       "description": "The OpenShift Namespace where the ImageStream resides.",
       "value": "openshift"
     },
     {
       "name": "MEMORY_LIMIT",
       "displayName": "Memory Limit",
+      "required": true,
       "description": "Maximum amount of memory the Django container can use.",
       "value": "512Mi"
     },
     {
       "name": "MEMORY_POSTGRESQL_LIMIT",
       "displayName": "Memory Limit (PostgreSQL)",
+      "required": true,
       "description": "Maximum amount of memory the PostgreSQL container can use.",
       "value": "512Mi"
     },
     {
       "name": "SOURCE_REPOSITORY_URL",
       "displayName": "Git Repository URL",
+      "required": true,
       "description": "The URL of the repository with your application source code.",
       "value": "https://github.com/openshift/django-ex.git"
     },
@@ -406,22 +416,26 @@
     {
       "name": "DATABASE_SERVICE_NAME",
       "displayName": "Database Service Name",
+      "required": true,
       "value": "postgresql"
     },
     {
       "name": "DATABASE_ENGINE",
       "displayName": "Database Engine",
+      "required": true,
       "description": "Database engine: postgresql, mysql or sqlite (default).",
       "value": "postgresql"
     },
     {
       "name": "DATABASE_NAME",
       "displayName": "Database Name",
+      "required": true,
       "value": "default"
     },
     {
       "name": "DATABASE_USER",
       "displayName": "Database Username",
+      "required": true,
       "value": "django"
     },
     {
@@ -441,6 +455,12 @@
       "description": "Set this to a long random string.",
       "generate": "expression",
       "from": "[\\w]{50}"
+    },
+    {
+      "name": "PIP_INDEX_URL",
+      "displayName": "Custom PyPi Index URL",
+      "description": "The custom PyPi index URL",
+      "value": ""
     }
   ]
 }

+ 16 - 1
roles/openshift_examples/files/examples/v1.2/quickstart-templates/django.json

@@ -84,7 +84,13 @@
               "kind": "ImageStreamTag",
               "namespace": "${NAMESPACE}",
               "name": "python:3.4"
-            }
+            },
+            "env": [
+              {
+                  "name": "PIP_INDEX_URL",
+                  "value": "${PIP_INDEX_URL}"
+              }
+            ]
           }
         },
         "output": {
@@ -233,18 +239,21 @@
     {
       "name": "NAMESPACE",
       "displayName": "Namespace",
+      "required": true,
       "description": "The OpenShift Namespace where the ImageStream resides.",
       "value": "openshift"
     },
     {
       "name": "MEMORY_LIMIT",
       "displayName": "Memory Limit",
+      "required": true,
       "description": "Maximum amount of memory the container can use.",
       "value": "512Mi"
     },
     {
       "name": "SOURCE_REPOSITORY_URL",
       "displayName": "Git Repository URL",
+      "required": true,
       "description": "The URL of the repository with your application source code.",
       "value": "https://github.com/openshift/django-ex.git"
     },
@@ -303,6 +312,12 @@
       "description": "Set this to a long random string.",
       "generate": "expression",
       "from": "[\\w]{50}"
+    },
+    {
+      "name": "PIP_INDEX_URL",
+      "displayName": "Custom PyPi Index URL",
+      "description": "The custom PyPi index URL",
+      "value": ""
     }
   ]
 }

+ 19 - 1
roles/openshift_examples/files/examples/v1.2/quickstart-templates/nodejs-mongodb.json

@@ -84,7 +84,13 @@
               "kind": "ImageStreamTag",
               "namespace": "${NAMESPACE}",
               "name": "nodejs:0.10"
-            }
+            },
+            "env":  [
+              {
+                  "name": "NPM_MIRROR",
+                  "value": "${NPM_MIRROR}"
+              }
+            ]
           }
         },
         "output": {
@@ -364,24 +370,28 @@
       "name": "NAMESPACE",
       "displayName": "Namespace",
       "description": "The OpenShift Namespace where the ImageStream resides.",
+      "required": true,
       "value": "openshift"
     },
     {
       "name": "MEMORY_LIMIT",
       "displayName": "Memory Limit",
       "description": "Maximum amount of memory the Node.js container can use.",
+      "required": true,
       "value": "512Mi"
     },
     {
       "name": "MEMORY_MONGODB_LIMIT",
       "displayName": "Memory Limit (MongoDB)",
       "description": "Maximum amount of memory the MongoDB container can use.",
+      "required": true,
       "value": "512Mi"
     },
     {
       "name": "SOURCE_REPOSITORY_URL",
       "displayName": "Git Repository URL",
       "description": "The URL of the repository with your application source code.",
+      "required": true,
       "value": "https://github.com/openshift/nodejs-ex.git"
     },
     {
@@ -417,6 +427,7 @@
     {
       "name": "DATABASE_SERVICE_NAME",
       "displayName": "Database Service Name",
+      "required": true,
       "value": "mongodb"
     },
     {
@@ -436,6 +447,7 @@
     {
       "name": "DATABASE_NAME",
       "displayName": "Database Name",
+      "required": true,
       "value": "sampledb"
     },
     {
@@ -444,6 +456,12 @@
       "description": "Password for the database admin user.",
       "generate": "expression",
       "from": "[a-zA-Z0-9]{16}"
+    },
+    {
+      "name": "NPM_MIRROR",
+      "displayName": "Custom NPM Mirror URL",
+      "description": "The custom NPM mirror URL",
+      "value": ""
     }
   ]
 }

+ 16 - 1
roles/openshift_examples/files/examples/v1.2/quickstart-templates/nodejs.json

@@ -84,7 +84,13 @@
               "kind": "ImageStreamTag",
               "namespace": "${NAMESPACE}",
               "name": "nodejs:0.10"
-            }
+            },
+            "env":  [
+              {
+                  "name": "NPM_MIRROR",
+                  "value": "${NPM_MIRROR}"
+              }
+            ]
           }
         },
         "output": {
@@ -237,18 +243,21 @@
       "name": "NAMESPACE",
       "displayName": "Namespace",
       "description": "The OpenShift Namespace where the ImageStream resides.",
+      "required": true,
       "value": "openshift"
     },
     {
       "name": "MEMORY_LIMIT",
       "displayName": "Memory Limit",
       "description": "Maximum amount of memory the container can use.",
+      "required": true,
       "value": "512Mi"
     },
     {
       "name": "SOURCE_REPOSITORY_URL",
       "displayName": "Git Repository URL",
       "description": "The URL of the repository with your application source code.",
+      "required": true,
       "value": "https://github.com/openshift/nodejs-ex.git"
     },
     {
@@ -303,6 +312,12 @@
       "name": "MONGODB_ADMIN_PASSWORD",
       "displayName": "Database Administrator Password",
       "description": "Password for the database admin user."
+    },
+    {
+      "name": "NPM_MIRROR",
+      "displayName": "Custom NPM Mirror URL",
+      "description": "The custom NPM mirror URL",
+      "value": ""
     }
   ]
 }

+ 22 - 1
roles/openshift_examples/files/examples/v1.2/quickstart-templates/rails-postgresql.json

@@ -84,7 +84,13 @@
               "kind": "ImageStreamTag",
               "namespace": "${NAMESPACE}",
               "name": "ruby:2.2"
-            }
+            },
+            "env": [
+              {
+                  "name": "RUBYGEM_MIRROR",
+                  "value": "${RUBYGEM_MIRROR}"
+              }
+            ]
           }
         },
         "output": {
@@ -394,24 +400,28 @@
     {
       "name": "NAMESPACE",
       "displayName": "Namespace",
+      "required": true,
       "description": "The OpenShift Namespace where the ImageStream resides.",
       "value": "openshift"
     },
     {
       "name": "MEMORY_LIMIT",
       "displayName": "Memory Limit",
+      "required": true,
       "description": "Maximum amount of memory the Rails container can use.",
       "value": "512Mi"
     },
     {
       "name": "MEMORY_POSTGRESQL_LIMIT",
       "displayName": "Memory Limit (PostgreSQL)",
+      "required": true,
       "description": "Maximum amount of memory the PostgreSQL container can use.",
       "value": "512Mi"
     },
     {
       "name": "SOURCE_REPOSITORY_URL",
       "displayName": "Git Repository URL",
+      "required": true,
       "description": "The URL of the repository with your application source code.",
       "value": "https://github.com/openshift/rails-ex.git"
     },
@@ -448,23 +458,27 @@
     {
       "name": "APPLICATION_USER",
       "displayName": "Application Username",
+      "required": true,
       "description": "The application user that is used within the sample application to authorize access on pages.",
       "value": "openshift"
     },
     {
       "name": "APPLICATION_PASSWORD",
       "displayName": "Application Password",
+      "required": true,
       "description": "The application password that is used within the sample application to authorize access on pages.",
       "value": "secret"
     },
     {
       "name": "RAILS_ENV",
       "displayName": "Rails Environment",
+      "required": true,
       "description": "Environment under which the sample application will run. Could be set to production, development or test.",
       "value": "production"
     },
     {
       "name": "DATABASE_SERVICE_NAME",
+      "required": true,
       "displayName": "Database Service Name",
       "value": "postgresql"
     },
@@ -482,6 +496,7 @@
     },
     {
       "name": "DATABASE_NAME",
+      "required": true,
       "displayName": "Database Name",
       "value": "root"
     },
@@ -494,6 +509,12 @@
       "name": "POSTGRESQL_SHARED_BUFFERS",
       "displayName": "Shared Buffer Amount",
       "value": "12MB"
+    },
+    {
+      "name": "RUBYGEM_MIRROR",
+      "displayName": "Custom RubyGems Mirror URL",
+      "description": "The custom RubyGems mirror URL",
+      "value": ""
     }
   ]
 }

+ 21 - 1
roles/openshift_examples/files/examples/v1.3/quickstart-templates/cakephp-mysql.json

@@ -84,7 +84,13 @@
               "kind": "ImageStreamTag",
               "namespace": "${NAMESPACE}",
               "name": "php:5.6"
-            }
+            },
+            "env":  [
+              {
+                  "name": "COMPOSER_MIRROR",
+                  "value": "${COMPOSER_MIRROR}"
+              }
+            ]
           }
         },
         "output": {
@@ -376,24 +382,28 @@
       "name": "NAMESPACE",
       "displayName": "Namespace",
       "description": "The OpenShift Namespace where the ImageStream resides.",
+      "required": true,
       "value": "openshift"
     },
     {
       "name": "MEMORY_LIMIT",
       "displayName": "Memory Limit",
       "description": "Maximum amount of memory the CakePHP container can use.",
+      "required": true,
       "value": "512Mi"
     },
     {
       "name": "MEMORY_MYSQL_LIMIT",
       "displayName": "Memory Limit (MySQL)",
       "description": "Maximum amount of memory the MySQL container can use.",
+      "required": true,
       "value": "512Mi"
     },
     {
       "name": "SOURCE_REPOSITORY_URL",
       "displayName": "Git Repository URL",
       "description": "The URL of the repository with your application source code.",
+      "required": true,
       "value": "https://github.com/openshift/cakephp-ex.git"
     },
     {
@@ -422,22 +432,26 @@
     {
       "name": "DATABASE_SERVICE_NAME",
       "displayName": "Database Service Name",
+      "required": true,
       "value": "mysql"
     },
     {
       "name": "DATABASE_ENGINE",
       "displayName": "Database Engine",
       "description": "Database engine: postgresql, mysql or sqlite (default).",
+      "required": true,
       "value": "mysql"
     },
     {
       "name": "DATABASE_NAME",
       "displayName": "Database Name",
+      "required": true,
       "value": "default"
     },
     {
       "name": "DATABASE_USER",
       "displayName": "Database User",
+      "required": true,
       "value": "cakephp"
     },
     {
@@ -472,6 +486,12 @@
       "displayName": "OPcache Revalidation Frequency",
       "description": "How often to check script timestamps for updates, in seconds. 0 will result in OPcache checking for updates on every request.",
       "value": "2"
+    },
+    {
+      "name": "COMPOSER_MIRROR",
+      "displayName": "Custom Composer Mirror URL",
+      "description": "The custom Composer mirror URL",
+      "value": ""
     }
   ]
 }

+ 17 - 2
roles/openshift_examples/files/examples/v1.3/quickstart-templates/cakephp.json

@@ -31,7 +31,7 @@
           }
         ],
         "selector": {
-          "name": "${NAME}" 
+          "name": "${NAME}"
         }
       }
     },
@@ -84,7 +84,13 @@
               "kind": "ImageStreamTag",
               "namespace": "${NAMESPACE}",
               "name": "php:5.6"
-            }
+            },
+            "env":  [
+              {
+                  "name": "COMPOSER_MIRROR",
+                  "value": "${COMPOSER_MIRROR}"
+              }
+            ]
           }
         },
         "output": {
@@ -239,18 +245,21 @@
       "name": "NAMESPACE",
       "displayName": "Namespace",
       "description": "The OpenShift Namespace where the ImageStream resides.",
+      "required": true,
       "value": "openshift"
     },
     {
       "name": "MEMORY_LIMIT",
       "displayName": "Memory Limit",
       "description": "Maximum amount of memory the container can use.",
+      "required": true,
       "value": "512Mi"
     },
     {
       "name": "SOURCE_REPOSITORY_URL",
       "displayName": "Git Repository URL",
       "description": "The URL of the repository with your application source code.",
+      "required": true,
       "value": "https://github.com/openshift/cakephp-ex.git"
     },
     {
@@ -323,6 +332,12 @@
       "displayName": "OPcache Revalidation Frequency",
       "description": "How often to check script timestamps for updates, in seconds. 0 will result in OPcache checking for updates on every request.",
       "value": "2"
+    },
+    {
+      "name": "COMPOSER_MIRROR",
+      "displayName": "Custom Composer Mirror URL",
+      "description": "The custom Composer mirror URL",
+      "value": ""
     }
   ]
 }

+ 19 - 1
roles/openshift_examples/files/examples/v1.3/quickstart-templates/dancer-mysql.json

@@ -84,7 +84,13 @@
               "kind": "ImageStreamTag",
               "namespace": "${NAMESPACE}",
               "name": "perl:5.20"
-            }
+            },
+            "env":  [
+              {
+                  "name": "CPAN_MIRROR",
+                  "value": "${CPAN_MIRROR}"
+              }
+            ]
           }
         },
         "output": {
@@ -350,24 +356,28 @@
       "name": "NAMESPACE",
       "displayName": "Namespace",
       "description": "The OpenShift Namespace where the ImageStream resides.",
+      "required": true,
       "value": "openshift"
     },
     {
       "name": "MEMORY_LIMIT",
       "displayName": "Memory Limit",
       "description": "Maximum amount of memory the Perl Dancer container can use.",
+      "required": true,
       "value": "512Mi"
     },
     {
       "name": "MEMORY_MYSQL_LIMIT",
       "displayName": "Memory Limit (MySQL)",
       "description": "Maximum amount of memory the MySQL container can use.",
+      "required": true,
       "value": "512Mi"
     },
     {
       "name": "SOURCE_REPOSITORY_URL",
       "displayName": "Git Repository URL",
       "description": "The URL of the repository with your application source code.",
+      "required": true,
       "value": "https://github.com/openshift/dancer-ex.git"
     },
     {
@@ -408,6 +418,7 @@
     {
       "name": "DATABASE_SERVICE_NAME",
       "displayName": "Database Service Name",
+      "required": true,
       "value": "database"
     },
     {
@@ -425,6 +436,7 @@
     {
       "name": "DATABASE_NAME",
       "displayName": "Database Name",
+      "required": true,
       "value": "sampledb"
     },
     {
@@ -439,6 +451,12 @@
       "description": "Your secret key for verifying the integrity of signed cookies.",
       "generate": "expression",
       "from": "[a-z0-9]{127}"
+    },
+    {
+      "name": "CPAN_MIRROR",
+      "displayName": "Custom CPAN Mirror URL",
+      "description": "The custom CPAN mirror URL",
+      "value": ""
     }
   ]
 }

+ 16 - 1
roles/openshift_examples/files/examples/v1.3/quickstart-templates/dancer.json

@@ -84,7 +84,13 @@
               "kind": "ImageStreamTag",
               "namespace": "${NAMESPACE}",
               "name": "perl:5.20"
-            }
+            },
+            "env":  [
+              {
+                  "name": "CPAN_MIRROR",
+                  "value": "${CPAN_MIRROR}"
+              }
+            ]
           }
         },
         "output": {
@@ -207,18 +213,21 @@
       "name": "NAMESPACE",
       "displayName": "Namespace",
       "description": "The OpenShift Namespace where the ImageStream resides.",
+      "required": true,
       "value": "openshift"
     },
     {
       "name": "MEMORY_LIMIT",
       "displayName": "Memory Limit",
       "description": "Maximum amount of memory the container can use.",
+      "required": true,
       "value": "512Mi"
     },
     {
       "name": "SOURCE_REPOSITORY_URL",
       "displayName": "Git Repository URL",
       "description": "The URL of the repository with your application source code.",
+      "required": true,
       "value": "https://github.com/openshift/dancer-ex.git"
     },
     {
@@ -256,6 +265,12 @@
       "displayName": "Perl Module Reload",
       "description": "Set this to \"true\" to enable automatic reloading of modified Perl modules.",
       "value": ""
+    },
+    {
+      "name": "CPAN_MIRROR",
+      "displayName": "Custom CPAN Mirror URL",
+      "description": "The custom CPAN mirror URL",
+      "value": ""
     }
   ]
 }

+ 21 - 1
roles/openshift_examples/files/examples/v1.3/quickstart-templates/django-postgresql.json

@@ -84,7 +84,13 @@
               "kind": "ImageStreamTag",
               "namespace": "${NAMESPACE}",
               "name": "python:3.4"
-            }
+            },
+            "env": [
+              {
+                  "name": "PIP_INDEX_URL",
+                  "value": "${PIP_INDEX_URL}"
+              }
+            ]
           }
         },
         "output": {
@@ -359,24 +365,28 @@
     {
       "name": "NAMESPACE",
       "displayName": "Namespace",
+      "required": true,
       "description": "The OpenShift Namespace where the ImageStream resides.",
       "value": "openshift"
     },
     {
       "name": "MEMORY_LIMIT",
       "displayName": "Memory Limit",
+      "required": true,
       "description": "Maximum amount of memory the Django container can use.",
       "value": "512Mi"
     },
     {
       "name": "MEMORY_POSTGRESQL_LIMIT",
       "displayName": "Memory Limit (PostgreSQL)",
+      "required": true,
       "description": "Maximum amount of memory the PostgreSQL container can use.",
       "value": "512Mi"
     },
     {
       "name": "SOURCE_REPOSITORY_URL",
       "displayName": "Git Repository URL",
+      "required": true,
       "description": "The URL of the repository with your application source code.",
       "value": "https://github.com/openshift/django-ex.git"
     },
@@ -406,22 +416,26 @@
     {
       "name": "DATABASE_SERVICE_NAME",
       "displayName": "Database Service Name",
+      "required": true,
       "value": "postgresql"
     },
     {
       "name": "DATABASE_ENGINE",
       "displayName": "Database Engine",
+      "required": true,
       "description": "Database engine: postgresql, mysql or sqlite (default).",
       "value": "postgresql"
     },
     {
       "name": "DATABASE_NAME",
       "displayName": "Database Name",
+      "required": true,
       "value": "default"
     },
     {
       "name": "DATABASE_USER",
       "displayName": "Database Username",
+      "required": true,
       "value": "django"
     },
     {
@@ -441,6 +455,12 @@
       "description": "Set this to a long random string.",
       "generate": "expression",
       "from": "[\\w]{50}"
+    },
+    {
+      "name": "PIP_INDEX_URL",
+      "displayName": "Custom PyPi Index URL",
+      "description": "The custom PyPi index URL",
+      "value": ""
     }
   ]
 }

+ 16 - 1
roles/openshift_examples/files/examples/v1.3/quickstart-templates/django.json

@@ -84,7 +84,13 @@
               "kind": "ImageStreamTag",
               "namespace": "${NAMESPACE}",
               "name": "python:3.4"
-            }
+            },
+            "env": [
+              {
+                  "name": "PIP_INDEX_URL",
+                  "value": "${PIP_INDEX_URL}"
+              }
+            ]
           }
         },
         "output": {
@@ -233,18 +239,21 @@
     {
       "name": "NAMESPACE",
       "displayName": "Namespace",
+      "required": true,
       "description": "The OpenShift Namespace where the ImageStream resides.",
       "value": "openshift"
     },
     {
       "name": "MEMORY_LIMIT",
       "displayName": "Memory Limit",
+      "required": true,
       "description": "Maximum amount of memory the container can use.",
       "value": "512Mi"
     },
     {
       "name": "SOURCE_REPOSITORY_URL",
       "displayName": "Git Repository URL",
+      "required": true,
       "description": "The URL of the repository with your application source code.",
       "value": "https://github.com/openshift/django-ex.git"
     },
@@ -303,6 +312,12 @@
       "description": "Set this to a long random string.",
       "generate": "expression",
       "from": "[\\w]{50}"
+    },
+    {
+      "name": "PIP_INDEX_URL",
+      "displayName": "Custom PyPi Index URL",
+      "description": "The custom PyPi index URL",
+      "value": ""
     }
   ]
 }

+ 19 - 1
roles/openshift_examples/files/examples/v1.3/quickstart-templates/nodejs-mongodb.json

@@ -84,7 +84,13 @@
               "kind": "ImageStreamTag",
               "namespace": "${NAMESPACE}",
               "name": "nodejs:0.10"
-            }
+            },
+            "env":  [
+              {
+                  "name": "NPM_MIRROR",
+                  "value": "${NPM_MIRROR}"
+              }
+            ]
           }
         },
         "output": {
@@ -364,24 +370,28 @@
       "name": "NAMESPACE",
       "displayName": "Namespace",
       "description": "The OpenShift Namespace where the ImageStream resides.",
+      "required": true,
       "value": "openshift"
     },
     {
       "name": "MEMORY_LIMIT",
       "displayName": "Memory Limit",
       "description": "Maximum amount of memory the Node.js container can use.",
+      "required": true,
       "value": "512Mi"
     },
     {
       "name": "MEMORY_MONGODB_LIMIT",
       "displayName": "Memory Limit (MongoDB)",
       "description": "Maximum amount of memory the MongoDB container can use.",
+      "required": true,
       "value": "512Mi"
     },
     {
       "name": "SOURCE_REPOSITORY_URL",
       "displayName": "Git Repository URL",
       "description": "The URL of the repository with your application source code.",
+      "required": true,
       "value": "https://github.com/openshift/nodejs-ex.git"
     },
     {
@@ -417,6 +427,7 @@
     {
       "name": "DATABASE_SERVICE_NAME",
       "displayName": "Database Service Name",
+      "required": true,
       "value": "mongodb"
     },
     {
@@ -436,6 +447,7 @@
     {
       "name": "DATABASE_NAME",
       "displayName": "Database Name",
+      "required": true,
       "value": "sampledb"
     },
     {
@@ -444,6 +456,12 @@
       "description": "Password for the database admin user.",
       "generate": "expression",
       "from": "[a-zA-Z0-9]{16}"
+    },
+    {
+      "name": "NPM_MIRROR",
+      "displayName": "Custom NPM Mirror URL",
+      "description": "The custom NPM mirror URL",
+      "value": ""
     }
   ]
 }

+ 16 - 1
roles/openshift_examples/files/examples/v1.3/quickstart-templates/nodejs.json

@@ -84,7 +84,13 @@
               "kind": "ImageStreamTag",
               "namespace": "${NAMESPACE}",
               "name": "nodejs:0.10"
-            }
+            },
+            "env":  [
+              {
+                  "name": "NPM_MIRROR",
+                  "value": "${NPM_MIRROR}"
+              }
+            ]
           }
         },
         "output": {
@@ -237,18 +243,21 @@
       "name": "NAMESPACE",
       "displayName": "Namespace",
       "description": "The OpenShift Namespace where the ImageStream resides.",
+      "required": true,
       "value": "openshift"
     },
     {
       "name": "MEMORY_LIMIT",
       "displayName": "Memory Limit",
       "description": "Maximum amount of memory the container can use.",
+      "required": true,
       "value": "512Mi"
     },
     {
       "name": "SOURCE_REPOSITORY_URL",
       "displayName": "Git Repository URL",
       "description": "The URL of the repository with your application source code.",
+      "required": true,
       "value": "https://github.com/openshift/nodejs-ex.git"
     },
     {
@@ -303,6 +312,12 @@
       "name": "MONGODB_ADMIN_PASSWORD",
       "displayName": "Database Administrator Password",
       "description": "Password for the database admin user."
+    },
+    {
+      "name": "NPM_MIRROR",
+      "displayName": "Custom NPM Mirror URL",
+      "description": "The custom NPM mirror URL",
+      "value": ""
     }
   ]
 }

+ 22 - 1
roles/openshift_examples/files/examples/v1.3/quickstart-templates/rails-postgresql.json

@@ -84,7 +84,13 @@
               "kind": "ImageStreamTag",
               "namespace": "${NAMESPACE}",
               "name": "ruby:2.2"
-            }
+            },
+            "env": [
+              {
+                  "name": "RUBYGEM_MIRROR",
+                  "value": "${RUBYGEM_MIRROR}"
+              }
+            ]
           }
         },
         "output": {
@@ -394,24 +400,28 @@
     {
       "name": "NAMESPACE",
       "displayName": "Namespace",
+      "required": true,
       "description": "The OpenShift Namespace where the ImageStream resides.",
       "value": "openshift"
     },
     {
       "name": "MEMORY_LIMIT",
       "displayName": "Memory Limit",
+      "required": true,
       "description": "Maximum amount of memory the Rails container can use.",
       "value": "512Mi"
     },
     {
       "name": "MEMORY_POSTGRESQL_LIMIT",
       "displayName": "Memory Limit (PostgreSQL)",
+      "required": true,
       "description": "Maximum amount of memory the PostgreSQL container can use.",
       "value": "512Mi"
     },
     {
       "name": "SOURCE_REPOSITORY_URL",
       "displayName": "Git Repository URL",
+      "required": true,
       "description": "The URL of the repository with your application source code.",
       "value": "https://github.com/openshift/rails-ex.git"
     },
@@ -448,23 +458,27 @@
     {
       "name": "APPLICATION_USER",
       "displayName": "Application Username",
+      "required": true,
       "description": "The application user that is used within the sample application to authorize access on pages.",
       "value": "openshift"
     },
     {
       "name": "APPLICATION_PASSWORD",
       "displayName": "Application Password",
+      "required": true,
       "description": "The application password that is used within the sample application to authorize access on pages.",
       "value": "secret"
     },
     {
       "name": "RAILS_ENV",
       "displayName": "Rails Environment",
+      "required": true,
       "description": "Environment under which the sample application will run. Could be set to production, development or test.",
       "value": "production"
     },
     {
       "name": "DATABASE_SERVICE_NAME",
+      "required": true,
       "displayName": "Database Service Name",
       "value": "postgresql"
     },
@@ -482,6 +496,7 @@
     },
     {
       "name": "DATABASE_NAME",
+      "required": true,
       "displayName": "Database Name",
       "value": "root"
     },
@@ -494,6 +509,12 @@
       "name": "POSTGRESQL_SHARED_BUFFERS",
       "displayName": "Shared Buffer Amount",
       "value": "12MB"
+    },
+    {
+      "name": "RUBYGEM_MIRROR",
+      "displayName": "Custom RubyGems Mirror URL",
+      "description": "The custom RubyGems mirror URL",
+      "value": ""
     }
   ]
 }

+ 0 - 51
roles/openshift_examples/tasks/main.yml

@@ -58,57 +58,6 @@
   failed_when: "'already exists' not in oex_import_infrastructure.stderr and oex_import_infrastructure.rc != 0"
   changed_when: false
 
-# The 1.1 release of the xpaas content for OpenShift renamed all the templates
-- name: Remove old xpaas templates from filesystem
-  file:
-    path: "{{ xpaas_templates_base }}/{{ item }}"
-    state: absent
-  with_items:
-    - amq6-persistent.json
-    - amq6.json
-    - eap6-amq-persistent-sti.json
-    - eap6-amq-sti.json
-    - eap6-basic-sti.json
-    - eap6-https-sti.json
-    - eap6-mongodb-persistent-sti.json
-    - eap6-mongodb-sti.json
-    - eap6-mysql-persistent-sti.json
-    - eap6-mysql-sti.json
-    - eap6-postgresql-persistent-sti.json
-    - eap6-postgresql-sti.json
-    - jws-tomcat7-basic-sti.json
-    - jws-tomcat7-https-sti.json
-    - jws-tomcat7-mongodb-sti.json
-    - jws-tomcat7-mongodb-persistent-sti.json
-    - jws-tomcat7-mysql-persistent-sti.json
-    - jws-tomcat7-mysql-sti.json
-    - jws-tomcat7-postgresql-persistent-sti.json
-    - jws-tomcat8-postgresql-persistent-sti.json
-    - jws-tomcat8-basic-sti.json
-    - jws-tomcat8-https-sti.json
-    - jws-tomcat8-mongodb-sti.json
-    - jws-tomcat8-mongodb-persistent-sti.json
-    - jws-tomcat8-mysql-sti.json
-    - jws-tomcat8-mysql-persistent-sti.json
-    - jws-tomcat8-postgresql-sti.json
-    - jws-tomcat7-postgresql-sti.json
-
-- name: Remove old xpaas templates from openshift namespace
-  command: >
-    {{ openshift.common.client_binary }} -n openshift delete
-    templates/amq6 templates/amq6-persistent templates/eap6-amq-persistent-sti templates/eap6-amq-sti \
-    templates/eap6-basic-sti templates/eap6-basic-sti templates/eap6-mongodb-persistent-sti templates/eap6-mongodb-sti \
-    templates/eap6-mysql-persistent-sti templates/eap6-mysql-sti templates/eap6-postgresql-persistent-sti \
-    templates/eap6-postgresql-sti templates/jws-tomcat7-basic-sti templates/jws-tomcat7-basic-sti \
-    templates/jws-tomcat7-mongodb-persistent-sti templates/jws-tomcat7-mongodb-sti \
-    templates/jws-tomcat7-mysql-persistent-sti templates/jws-tomcat7-mysql-sti \
-    templates/jws-tomcat7-postgresql-persistent-sti templates/jws-tomcat7-postgresql-sti \
-    templates/jws-tomcat8-basic-sti templates/jws-tomcat8-basic-sti templates/jws-tomcat8-mongodb-persistent-sti
-  when: openshift_examples_load_xpaas | bool
-  register: oex_delete_old_xpaas_templates
-  failed_when: "'not found' not in oex_delete_old_xpaas_templates.stderr and oex_delete_old_xpaas_templates.rc != 0"
-  changed_when: false
-
 - name: Import xPaas image streams
   command: >
     {{ openshift.common.client_binary }} {{ openshift_examples_import_command }} -n openshift -f {{ xpaas_image_streams }}

+ 1 - 0
roles/openshift_expand_partition/meta/main.yml

@@ -15,3 +15,4 @@ galaxy_info:
   categories:
     - openshift
     - cloud
+dependencies: []

+ 11 - 5
roles/openshift_facts/library/openshift_facts.py

@@ -115,6 +115,12 @@ def migrate_hosted_facts(facts):
             if 'router' not in facts['hosted']:
                 facts['hosted']['router'] = {}
             facts['hosted']['router']['selector'] = facts['master'].pop('router_selector')
+        if 'registry_selector' in facts['master']:
+            if 'hosted' not in facts:
+                facts['hosted'] = {}
+            if 'registry' not in facts['hosted']:
+                facts['hosted']['registry'] = {}
+            facts['hosted']['registry']['selector'] = facts['master'].pop('registry_selector')
     return facts
 
 def first_ip(network):
@@ -467,11 +473,11 @@ def set_selectors(facts):
         facts['hosted']['router'] = {}
     if 'selector' not in facts['hosted']['router'] or facts['hosted']['router']['selector'] in [None, 'None']:
         facts['hosted']['router']['selector'] = selector
+    if 'registry' not in facts['hosted']:
+        facts['hosted']['registry'] = {}
+    if 'selector' not in facts['hosted']['registry'] or facts['hosted']['registry']['selector'] in [None, 'None']:
+        facts['hosted']['registry']['selector'] = selector
 
-    if 'master' in facts:
-        if 'infra_nodes' in facts['master']:
-            if 'registry_selector' not in facts['master']:
-                facts['master']['registry_selector'] = selector
     return facts
 
 def set_metrics_facts_if_unset(facts):
@@ -1594,7 +1600,7 @@ class OpenShiftFacts(object):
                    'node']
 
     # Disabling too-many-arguments, this should be cleaned up as a TODO item.
-    # pylint: disable=too-many-arguments
+    # pylint: disable=too-many-arguments,no-value-for-parameter
     def __init__(self, role, filename, local_facts,
                  additive_facts_to_overwrite=None,
                  openshift_env=None,

+ 12 - 8
roles/openshift_hosted/README.md

@@ -4,24 +4,27 @@ OpenShift Hosted
 OpenShift Hosted Resources
 
 * OpenShift Router
+* OpenShift Registry
 
 Requirements
 ------------
 
-This role requires a running OpenShift cluster with nodes labeled to
-match the openshift_hosted_router_selector (default: region=infra).
+This role requires a running OpenShift cluster.
 
 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. |
+| Name                                  | Default value                            | Description                                                                                                              |
+|---------------------------------------|------------------------------------------|--------------------------------------------------------------------------------------------------------------------------|
+| openshift_hosted_router_certificate   | None                                     | Dictionary containing "certfile", "keyfile" and "cafile" 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.     |
+| openshift_hosted_registry_registryurl | 'openshift3/ose-${component}:${version}' | The image to base the OpenShift registry on.                                                                             |
+| openshift_hosted_registry_replicas    | Number of nodes matching selector        | The number of replicas to configure.                                                                                     |
+| openshift_hosted_registry_selector    | region=infra                             | Node selector used when creating registry. The OpenShift registry will only be deployed to nodes matching this selector. |
 
 Dependencies
 ------------
@@ -40,6 +43,7 @@ Example Playbook
     openshift_hosted_router_certificate:
       certfile: /path/to/my-router.crt
       keyfile: /path/to/my-router.key
+      cafile: /path/to/my-router-ca.crt
     openshift_hosted_router_registryurl: 'registry.access.redhat.com/openshift3/ose-haproxy-router:v3.0.2.0'
     openshift_hosted_router_selector: 'type=infra'
 ```

roles/openshift_registry/defaults/main.yml → roles/openshift_hosted/defaults/main.yml


+ 23 - 2
roles/openshift_hosted/meta/main.yml

@@ -12,5 +12,26 @@ galaxy_info:
   categories:
   - cloud
 dependencies:
-- openshift_common
-- openshift_hosted_facts
+- role: openshift_cli
+- role: openshift_hosted_facts
+- role: openshift_projects
+  # TODO: Move standard project definitions to openshift_hosted/vars/main.yml
+  # Vars are not accessible in meta/main.yml in ansible-1.9.x
+  openshift_projects: "{{ openshift_additional_projects | default({}) | oo_merge_dicts({'default':{'default_node_selector':''},'openshift-infra':{'default_node_selector':''},'logging':{'default_node_selector':''}}) }}"
+- role: openshift_serviceaccounts
+  openshift_serviceaccounts_names:
+  - router
+  openshift_serviceaccounts_namespace: default
+  openshift_serviceaccounts_sccs:
+  - hostnetwork
+  when: openshift.common.version_gte_3_2_or_1_2
+- role: openshift_serviceaccounts
+  openshift_serviceaccounts_names:
+  - router
+  - registry
+  openshift_serviceaccounts_namespace: default
+  openshift_serviceaccounts_sccs:
+  - privileged
+  when: not openshift.common.version_gte_3_2_or_1_2
+- role: openshift_metrics
+  when: openshift.hosted.metrics.deploy | bool

+ 20 - 1
roles/openshift_hosted/tasks/main.yml

@@ -1,3 +1,22 @@
 ---
+- name: Create temp directory for kubeconfig
+  command: mktemp -d /tmp/openshift-ansible-XXXXXX
+  register: mktemp
+  changed_when: False
 
-- include: router.yml
+- set_fact:
+    openshift_hosted_kubeconfig: "{{ mktemp.stdout }}/admin.kubeconfig"
+
+- name: Copy the admin client config(s)
+  command: >
+    cp {{ openshift_master_config_dir }}/admin.kubeconfig {{ openshift_hosted_kubeconfig }}
+  changed_when: False
+
+- include: router/router.yml
+- include: registry/registry.yml
+
+- name: Delete temp directory
+  file:
+    name: "{{ mktemp.stdout }}"
+    state: absent
+  changed_when: False

+ 40 - 0
roles/openshift_hosted/tasks/registry/registry.yml

@@ -0,0 +1,40 @@
+---
+- name: Retrieve list of openshift nodes matching registry selector
+  command: >
+    {{ openshift.common.client_binary }} --api-version='v1' -o json
+    get nodes -n default --config={{ openshift_hosted_kubeconfig }}
+    --selector={{ openshift.hosted.registry.selector | default('') }}
+  register: openshift_hosted_registry_nodes_json
+  changed_when: false
+  when: openshift.hosted.registry.replicas | default(none) is none
+
+- set_fact:
+    replicas: "{{ openshift.hosted.registry.replicas | default(((openshift_hosted_registry_nodes_json.stdout | from_json)['items'] | length) if openshift.hosted.registry.storage.kind | default(none) is not none else 1) }}"
+
+- name: Create OpenShift registry
+  command: >
+    {{ openshift.common.admin_binary }} registry --create
+    --config={{ openshift_hosted_kubeconfig }}
+    {% if replicas > 1 -%}
+    --replicas={{ replicas }}
+    {% endif -%}
+    --namespace={{ openshift.hosted.registry.namespace | default('default') }}
+    --service-account=registry
+    {% if openshift.hosted.registry.selector | default(none) is not none -%}
+    --selector='{{ openshift.hosted.registry.selector }}'
+    {% endif -%}
+    {% if not openshift.common.version_gte_3_2_or_1_2 | bool -%}
+    --credentials={{ openshift_master_config_dir }}/openshift-registry.kubeconfig
+    {% endif -%}
+    {% if openshift.hosted.registry.registryurl | default(none) is not none -%}
+    --images='{{ openshift.hosted.registry.registryurl }}'
+    {% endif -%}
+  register: openshift_hosted_registry_results
+  changed_when: "'service exists' not in openshift_hosted_registry_results.stdout"
+  failed_when: "openshift_hosted_registry_results.rc != 0 and 'service exists' not in openshift_hosted_registry_results.stdout and 'deployment_config' not in openshift_hosted_registry_results.stderr and 'service' not in openshift_hosted_registry_results.stderr"
+
+- include: storage/object_storage.yml
+  when: openshift.hosted.registry.storage.kind | default(none) == 'object'
+
+- include: storage/persistent_volume.yml
+  when: openshift.hosted.registry.storage.kind | default(none) in ['nfs', 'openstack']

+ 114 - 0
roles/openshift_hosted/tasks/registry/storage/object_storage.yml

@@ -0,0 +1,114 @@
+- fail:
+    msg: >
+      Object Storage Provider: {{ openshift.hosted.registry.storage.provider }}
+      is not currently supported
+  when: openshift.hosted.registry.storage.provider not in ['azure_blob', 's3', 'swift']
+
+- fail:
+    msg: >
+      Support for provider: "{{ openshift.hosted.registry.storage.provider }}"
+      not implemented yet
+  when: openshift.hosted.registry.storage.provider in ['azure_blob', 'swift']
+
+- include: s3.yml
+  when: openshift.hosted.registry.storage.provider == 's3'
+
+- name: Test if docker registry config secret exists
+  command: >
+    {{ openshift.common.client_binary }}
+    --config={{ openshift_hosted_kubeconfig }}
+    --namespace={{ openshift.hosted.registry.namespace | default('default') }}
+    get secrets {{ registry_config_secret_name }} -o json
+  register: secrets
+  changed_when: false
+  failed_when: false
+
+- set_fact:
+    registry_config: "{{ lookup('template', '../templates/registry_config.j2') | b64encode }}"
+
+- set_fact:
+    registry_config_secret: "{{ lookup('template', '../templates/registry_config_secret.j2') | from_yaml }}"
+
+- set_fact:
+    same_storage_provider: "{{ (secrets.stdout|from_json)['metadata']['annotations']['provider'] | default(none) == openshift.hosted.registry.storage.provider }}"
+  when: secrets.rc == 0
+
+- name: Update registry config secret
+  command: >
+    {{ openshift.common.client_binary }}
+    --config={{ openshift_hosted_kubeconfig }}
+    --namespace={{ openshift.hosted.registry.namespace | default('default') }}
+    patch secret/{{ registry_config_secret_name }}
+    -p '{"data": {"config.yml": "{{ registry_config }}"}}'
+  register: update_config_secret
+  when: secrets.rc == 0 and (secrets.stdout|from_json)['data']['config.yml'] != registry_config and same_storage_provider | bool
+
+- name: Create registry config secret
+  shell: >
+    echo '{{ registry_config_secret |to_json }}' |
+    {{ openshift.common.client_binary }}
+    --config={{ openshift_hosted_kubeconfig }}
+    --namespace={{ openshift.hosted.registry.namespace | default('default') }}
+    create -f -
+  when: secrets.rc == 1
+
+- name: Determine if service account contains secrets
+  command: >
+    {{ openshift.common.client_binary }}
+    --config={{ openshift_hosted_kubeconfig }}
+    --namespace={{ openshift.hosted.registry.namespace | default('default') }}
+    get serviceaccounts registry
+    -o jsonpath='{.secrets[?(@.name=="{{ registry_config_secret_name }}")].name}'
+  register: serviceaccount
+  changed_when: false
+
+- name: Add secrets to registry service account
+  command: >
+    {{ openshift.common.client_binary }}
+    --config={{ openshift_hosted_kubeconfig }}
+    --namespace={{ openshift.hosted.registry.namespace | default('default') }}
+    secrets add serviceaccount/registry secrets/{{ registry_config_secret_name }}
+  when: serviceaccount.stdout == ''
+
+- name: Determine if deployment config contains secrets
+  command: >
+    {{ openshift.common.client_binary }}
+    --config={{ openshift_hosted_kubeconfig }}
+    --namespace={{ openshift.hosted.registry.namespace | default('default') }}
+    set volumes dc/docker-registry --list
+  register: volume
+  changed_when: false
+
+- name: Add secrets to registry deployment config
+  command: >
+    {{ openshift.common.client_binary }}
+    --config={{ openshift_hosted_kubeconfig }}
+    --namespace={{ openshift.hosted.registry.namespace | default('default') }}
+    set volumes dc/docker-registry --add --name=docker-config -m /etc/registry
+    --type=secret --secret-name={{ registry_config_secret_name }}
+  when: registry_config_secret_name not in volume.stdout
+
+- name: Determine if registry environment variable needs to be created
+  command: >
+    {{ openshift.common.client_binary }}
+    --config={{ openshift_hosted_kubeconfig }}
+    --namespace={{ openshift.hosted.registry.namespace | default('default') }}
+    set env --list dc/docker-registry
+  register: oc_env
+  changed_when: false
+
+- name: Add registry environment variable
+  command: >
+    {{ openshift.common.client_binary }}
+    --config={{ openshift_hosted_kubeconfig }}
+    --namespace={{ openshift.hosted.registry.namespace | default('default') }}
+    set env dc/docker-registry REGISTRY_CONFIGURATION_PATH=/etc/registry/config.yml
+  when: "'REGISTRY_CONFIGURATION_PATH' not in oc_env.stdout"
+
+- name: Redeploy registry
+  command: >
+    {{ openshift.common.client_binary }}
+    --config={{ openshift_hosted_kubeconfig }}
+    --namespace={{ openshift.hosted.registry.namespace | default('default') }}
+    deploy dc/docker-registry --latest
+  when: secrets.rc == 0 and update_config_secret.rc == 0 and same_storage_provider | bool

+ 3 - 9
roles/openshift_registry/tasks/main.yml

@@ -1,15 +1,9 @@
 ---
-- name: Deploy OpenShift Registry
-  command: >
-    {{ openshift.common.admin_binary }} registry
-    --create --replicas={{ openshift.master.infra_nodes | length }}
-    --service-account=registry {{ oreg_selector }}
-    --credentials={{ openshift_master_config_dir }}/openshift-registry.kubeconfig {{ oreg_images }}
-  register: oreg_results
-  changed_when: "'service exists' not in oreg_results.stdout"
+- set_fact:
+    registry_volume_claim: "{{ openshift.hosted.registry.storage.volume.name }}-claim"
 
 - name: Determine if volume is already attached to dc/docker-registry
-  command: "{{ openshift.common.client_binary }} get -o template dc/docker-registry --template=\\{\\{.spec.template.spec.volumes\\}\\}"
+  command: "{{ openshift.common.client_binary }} get -o template dc/docker-registry --template=\\{\\{.spec.template.spec.volumes\\}\\} --output-version=v1"
   changed_when: false
   register: registry_volumes_output
 

+ 12 - 0
roles/openshift_hosted/tasks/registry/storage/s3.yml

@@ -0,0 +1,12 @@
+---
+- fail:
+    msg: >
+      openshift_hosted_registry_storage_s3_accesskey and
+      openshift_hosted_registry_storage_s3_secretkey are required
+  when: openshift.hosted.registry.storage.s3.accesskey | default(none) is none or openshift.hosted.registry.storage.s3.secretkey | default(none) is none
+
+- fail:
+    msg: >
+      openshift_hosted_registry_storage_s3_bucket and
+      openshift_hosted_registry_storage_s3_region are required
+  when: openshift.hosted.registry.storage.s3.bucket | default(none) is none or openshift.hosted.registry.storage.s3.region | default(none) is none

+ 0 - 65
roles/openshift_hosted/tasks/router.yml

@@ -1,65 +0,0 @@
----
-- 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
-  changed_when: false
-  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)

+ 70 - 0
roles/openshift_hosted/tasks/router/router.yml

@@ -0,0 +1,70 @@
+---
+- fail:
+    msg: "'certfile', 'keyfile' and 'cafile' 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 or 'cafile' not in openshift_hosted_router_certificate) 
+
+- name: Read router certificate and key
+  become: no
+  local_action:
+    module: slurp
+    src: "{{ item }}"
+  register: openshift_router_certificate_output
+  with_items:
+  - "{{ openshift_hosted_router_certificate.certfile }}"
+  - "{{ openshift_hosted_router_certificate.keyfile }}"
+  - "{{ openshift_hosted_router_certificate.cafile }}"
+  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) is not none
+
+- name: Retrieve list of openshift nodes matching router selector
+  command: >
+    {{ openshift.common.client_binary }} --api-version='v1' -o json
+    get nodes -n default --config={{ openshift_hosted_kubeconfig }}
+    --selector={{ openshift.hosted.router.selector | default('') }}
+  register: openshift_hosted_router_nodes_json
+  changed_when: false
+  when: openshift.hosted.router.replicas | default(none) is none
+
+- set_fact:
+    replicas: "{{ openshift.hosted.router.replicas | default((openshift_hosted_router_nodes_json.stdout | from_json)['items'] | length) }}"
+
+- name: Create OpenShift router
+  command: >
+    {{ openshift.common.admin_binary }} router --create
+    --config={{ openshift_hosted_kubeconfig }}
+    {% if replicas > 1 -%}
+    --replicas={{ replicas }}
+    {% endif -%}
+    {% if openshift.hosted.router.certificate | default(none) is not none -%}
+    --default-cert={{ openshift_master_config_dir }}/openshift-router.pem
+    {% endif -%}
+    --namespace={{ openshift.hosted.router.namespace | default('default') }}
+    {% if openshift.hosted.router.force_subdomain | default(none) is not none %}
+    --force-subdomain={{ openshift.hosted.router.force_subdomain }}
+    {% endif %}
+    --service-account=router
+    {% if openshift.hosted.router.selector | default(none) is not none -%}
+    --selector='{{ openshift.hosted.router.selector }}'
+    {% endif -%}
+    {% if not openshift.common.version_gte_3_2_or_1_2 | bool -%}
+    --credentials={{ openshift_master_config_dir }}/openshift-router.kubeconfig
+    {% endif -%}
+    {% if openshift.hosted.router.registryurl | default(none) is not none -%}
+    --images='{{ openshift.hosted.router.registryurl }}'
+    {% endif -%}
+  register: openshift_hosted_router_results
+  changed_when: "'service exists' not in openshift_hosted_router_results.stdout"
+  failed_when: "openshift_hosted_router_results.rc != 0 and 'service exists' not in openshift_hosted_router_results.stdout and 'deployment_config' not in openshift_hosted_router_results.stderr and 'service' not in openshift_hosted_router_results.stderr"

+ 72 - 0
roles/openshift_hosted/templates/registry_config.j2

@@ -0,0 +1,72 @@
+version: 0.1
+log:
+  level: debug
+http:
+  addr: :5000
+storage:
+  cache:
+    blobdescriptor: inmemory
+{% if openshift.hosted.registry.storage.provider == 's3' %}
+  s3:
+    accesskey: {{ openshift.hosted.registry.storage.s3.accesskey }}
+    secretkey: {{ openshift.hosted.registry.storage.s3.secretkey }}
+    region: {{ openshift.hosted.registry.storage.s3.region }}
+    bucket: {{ openshift.hosted.registry.storage.s3.bucket }}
+    encrypt: false
+    secure: true
+    v4auth: true
+    rootdirectory: /registry
+    chunksize: "{{ openshift.hosted.registry.storage.s3.chunksize | default(26214400) }}"
+{% elif openshift.hosted.registry.storage.provider == 'azure_blob' %}
+  azure:
+    accountname: {{ openshift.hosted.registry.storage.azure_blob.accountname }}
+    accountkey: {{ openshift.hosted.registry.storage.azure_blob.accountkey }}
+    container: {{ openshift.hosted.registry.storage.azure_blob.container }}
+    realm: {{ openshift.hosted.registry.storage.azure_blob.realm }}
+{% elif openshift.hosted.registry.storage.provider == 'swift' %}
+  swift:
+    authurl: {{ openshift.hosted.registry.storage.swift.authurl }}
+    username: {{ openshift.hosted.registry.storage.swift.username }}
+    password: {{ openshift.hosted.registry.storage.swift.password }}
+    container: {{ openshift.hosted.registry.storage.swift.container }}
+{%   if 'region' in openshift.hosted.registry.storage.swift %}
+    region: {{ openshift.hosted.registry.storage.swift.region }}
+{%   endif -%}
+{%   if 'tenant' in openshift.hosted.registry.storage.swift %}
+    tenant: {{ openshift.hosted.registry.storage.swift.tenant }}
+{%   endif -%}
+{%   if 'tenantid' in openshift.hosted.registry.storage.swift %}
+    tenantid: {{ openshift.hosted.registry.storage.swift.tenantid }}
+{%   endif -%}
+{%   if 'domain' in openshift.hosted.registry.storage.swift %}
+    domain: {{ openshift.hosted.registry.storage.swift.domain }}
+{%   endif -%}
+{%   if 'domainid' in openshift.hosted.registry.storage.swift %}
+    domainid: {{ openshift.hosted.registry.storage.swift.domainid }}
+{%   endif -%}
+{% elif openshift.hosted.registry.storage.provider == 'gcs' %}
+  gcs:
+    bucket: {{ openshift.hosted.registry.storage.gcs.bucket }}
+{%   if 'keyfile' in openshift.hosted.registry.storage.gcs %}
+    keyfile: {{ openshift.hosted.registry.storage.gcs.keyfile }}
+{%   endif -%}
+{%   if 'rootdirectory' in openshift.hosted.registry.storage.gcs %}
+    rootdirectory: {{ openshift.hosted.registry.storage.gcs.rootdirectory }}
+{%   endif -%}
+{% endif -%}
+auth:
+  openshift:
+    realm: openshift
+middleware:
+  repository:
+  - name: openshift
+    options:
+      pullthrough: {{ openshift.hosted.registry.pullthrough | default(true) }}
+{% if openshift.hosted.registry.storage.provider == 's3' and 'cloudfront' in openshift.hosted.registry.storage.s3 %}
+  storage:
+  - name: cloudfront
+    options:
+      baseurl: {{ openshift.hosted.registry.storage.s3.cloudfront.baseurl }}
+      privatekey: {{ openshift.hosted.registry.storage.s3.cloudfront.privatekeyfile }}
+      keypairid: {{ openshift.hosted.registry.storage.s3.cloudfront.keypairid }}
+{% endif -%}

+ 9 - 0
roles/openshift_hosted/templates/registry_config_secret.j2

@@ -0,0 +1,9 @@
+---
+apiVersion: v1
+kind: Secret
+metadata:
+  name: registry-config
+  annotations:
+    provider: {{ openshift.hosted.registry.storage.provider }}
+data:
+  config.yml: {{ registry_config }}

+ 1 - 0
roles/openshift_hosted/vars/main.yml

@@ -1,2 +1,3 @@
 ---
 openshift_master_config_dir: "{{ openshift.common.config_base }}/master"
+registry_config_secret_name: registry-config

+ 9 - 0
roles/openshift_hosted_facts/tasks/main.yml

@@ -1,7 +1,16 @@
 ---
+- set_fact:
+    openshift_hosted_router_selector: "{{ openshift_hosted_infra_selector }}"
+  when: openshift_hosted_router_selector is not defined and openshift_hosted_infra_selector is defined
+- set_fact:
+    openshift_hosted_registry_selector: "{{ openshift_hosted_infra_selector }}"
+  when: openshift_hosted_registry_selector is not defined and openshift_hosted_infra_selector is defined
+
 - name: Set hosted facts
   openshift_facts:
     role: hosted
     openshift_env: "{{ hostvars
                        | oo_merge_hostvars(vars, inventory_hostname)
                        | oo_openshift_env }}"
+    openshift_env_structures:
+    - 'openshift.hosted.router.*'

+ 2 - 0
roles/openshift_master/README.md

@@ -13,6 +13,7 @@ Role Variables
 --------------
 
 From this role:
+
 | Name                                | Default value         |                                                  |
 |-------------------------------------|-----------------------|--------------------------------------------------|
 | openshift_master_debug_level        | openshift_debug_level | Verbosity of the debug logs for master |
@@ -26,6 +27,7 @@ From this role:
 | openshift_master_public_console_url | UNDEF                 | |
 
 From openshift_common:
+
 | Name                          | Default Value  |                                        |
 |-------------------------------|----------------|----------------------------------------|
 | openshift_debug_level         | 2              | Global openshift debug log verbosity   |

+ 0 - 1
roles/openshift_master_facts/tasks/main.yml

@@ -61,7 +61,6 @@
       registry_selector: "{{ openshift_registry_selector | default(None) }}"
       api_server_args: "{{ osm_api_server_args | default(None) }}"
       controller_args: "{{ osm_controller_args | default(None) }}"
-      infra_nodes: "{{ openshift_infra_nodes | default(None) }}"
       disabled_features: "{{ osm_disabled_features | default(None) }}"
       master_count: "{{ openshift_master_count | default(None) }}"
       controller_lease_ttl: "{{ osm_controller_lease_ttl | default(None) }}"

+ 7 - 7
roles/openshift_metrics/README.md

@@ -15,13 +15,13 @@ From this role:
 
 | Name                                            | Default value         |                                                             |
 |-------------------------------------------------|-----------------------|-------------------------------------------------------------|
-| openshift_hosted_metrics_deploy                 | False                 | If metrics should be deployed                               |
-| openshift_hosted_metrics_storage_nfs_directory  | /exports              | Root export directory.                                      |
-| openshift_hosted_metrics_storage_volume_name    | metrics               | Metrics volume within openshift_hosted_metrics_volume_dir   |
-| openshift_hosted_metrics_storage_volume_size    | 10Gi                  | Metrics volume size                                         |
-| openshift_hosted_metrics_storage_nfs_options    | *(rw,root_squash)     | NFS options for configured exports.                         |
-| openshift_hosted_metrics_duration               | 7                     | Metrics query duration                                      |
-| openshift_hosted_metrics_resolution             | 10s                   | Metrics resolution                                          |
+| openshift_hosted_metrics_deploy                 | `False`               | If metrics should be deployed                               |
+| openshift_hosted_metrics_storage_nfs_directory  | `/exports`            | Root export directory.                                      |
+| openshift_hosted_metrics_storage_volume_name    | `metrics`             | Metrics volume within openshift_hosted_metrics_volume_dir   |
+| openshift_hosted_metrics_storage_volume_size    | `10Gi`                | Metrics volume size                                         |
+| openshift_hosted_metrics_storage_nfs_options    | `*(rw,root_squash)`   | NFS options for configured exports.                         |
+| openshift_hosted_metrics_duration               | `7`                   | Metrics query duration                                      |
+| openshift_hosted_metrics_resolution             | `10s`                 | Metrics resolution                                          |
 
 
 From openshift_common:

+ 2 - 0
roles/openshift_node/README.md

@@ -14,12 +14,14 @@ rhel-7-server-extras-rpms, and rhel-7-server-ose-3.0-rpms repos.
 Role Variables
 --------------
 From this role:
+
 | Name                                     | Default value         |                                                        |
 |------------------------------------------|-----------------------|--------------------------------------------------------|
 | openshift_node_debug_level               | openshift_debug_level | Verbosity of the debug logs for node |
 | oreg_url                                 | UNDEF (Optional)      | Default docker registry to use                         |
 
 From openshift_common:
+
 | Name                          |  Default Value      |                     |
 |-------------------------------|---------------------|---------------------|
 | openshift_debug_level         | 2                   | Global openshift debug log verbosity |

+ 5 - 0
roles/openshift_persistent_volumes/README.md

@@ -10,6 +10,7 @@ Role Variables
 --------------
 
 From this role:
+
 | Name                     | Default value |                                                                                     |
 |--------------------------|---------------|-------------------------------------------------------------------------------------|
 | persistent_volumes       | []            | List of persistent volume dictionaries, keys: name, capacity, access_modes, storage |
@@ -17,6 +18,7 @@ From this role:
 
 
 From openshift_common:
+
 | Name                          | Default Value  |                                        |
 |-------------------------------|----------------|----------------------------------------|
 | openshift_debug_level         | 2              | Global openshift debug log verbosity   |
@@ -29,6 +31,7 @@ Dependencies
 Example Playbook
 ----------------
 
+```
 - name: Create persistent volumes/claims
   hosts: oo_first_master
   vars:
@@ -48,6 +51,8 @@ Example Playbook
       - "ReadWriteMany"
   roles:
   - role: openshift_persistent_volumes
+```
+
 
 License
 -------

+ 3 - 3
roles/openshift_registry/meta/main.yml

@@ -1,7 +1,7 @@
 ---
 galaxy_info:
-  author: OpenShift Red Hat
-  description: OpenShift Embedded Docker Registry
+  author: Jason DeTiberus
+  description: OpenShift Projects
   company: Red Hat, Inc.
   license: Apache License, Version 2.0
   min_ansible_version: 1.9
@@ -12,4 +12,4 @@ galaxy_info:
   categories:
   - cloud
 dependencies:
-- role: openshift_hosted_facts
+- { role: openshift_facts }

+ 47 - 0
roles/openshift_projects/tasks/main.yml

@@ -0,0 +1,47 @@
+---
+- name: Create temp directory for kubeconfig
+  command: mktemp -d /tmp/openshift-ansible-XXXXXX
+  register: mktemp
+  changed_when: False
+
+- name: Copy the admin client config(s)
+  command: >
+    cp {{ openshift_master_config_dir }}/admin.kubeconfig {{ mktemp.stdout }}/admin.kubeconfig
+  changed_when: False
+
+- name: Determine if projects exist
+  command: >
+    {{ openshift.common.client_binary }} --config={{ mktemp.stdout }}/admin.kubeconfig
+    get projects {{ item.key }} -o json
+  with_dict: "{{ openshift_projects }}"
+  failed_when: false
+  changed_when: false
+  register: project_test
+
+- name: Create projects
+  command: >
+    {{ openshift.common.admin_binary }} --config={{ mktemp.stdout }}/admin.kubeconfig
+    new-project {{ item.item.key }}
+    {% if item.item.value.default_node_selector | default(none) != none %}
+    {{ '--node-selector=' ~ item.item.value.default_node_selector }}
+    {% endif %}
+  when: item.rc == 1
+  with_items:
+  - "{{ project_test.results }}"
+
+- name: Update project default node selector if necessary
+  command: >
+    {{ openshift.common.client_binary }}
+    --config={{ mktemp.stdout }}/admin.kubeconfig patch namespace {{ item.item.key }}
+    -p '{"metadata": {"annotations": {"openshift.io/node-selector": "{{ item.item.value.default_node_selector }}"}}}'
+  when: "{{ item.rc == 0 and item.item.value.default_node_selector | default(none) != none
+            and item.item.value.default_node_selector | default(none) != (item.stdout | from_json).metadata.annotations['openshift.io/node-selector'] | default(none) }}"
+  with_items:
+  - "{{ project_test.results }}"
+  register: annotate_project
+
+- name: Delete temp directory
+  file:
+    name: "{{ mktemp.stdout }}"
+    state: absent
+  changed_when: False

+ 2 - 0
roles/openshift_projects/vars/main.yml

@@ -0,0 +1,2 @@
+---
+openshift_master_config_dir: "{{ openshift.common.config_base }}/master"

+ 0 - 37
roles/openshift_registry/README.md

@@ -1,37 +0,0 @@
-OpenShift Container Docker Registry
-===================================
-
-OpenShift Docker Registry  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

+ 0 - 0
roles/openshift_registry/handlers/main.yml


+ 0 - 4
roles/openshift_registry/vars/main.yml

@@ -1,4 +0,0 @@
----
-openshift_master_config_dir: "{{ openshift.common.config_base }}/master"
-oreg_images: "--images='{{ openshift.master.registry_url }}'"
-oreg_selector: "--selector='{{ openshift.master.registry_selector }}'"

roles/openshift_repos/files/rhel-origin/RPM-GPG-KEY-CentOS-SIG-PaaS → roles/openshift_repos/files/origin/gpg_keys/openshift-ansible-CentOS-SIG-PaaS


+ 4 - 5
roles/openshift_repos/files/rhel-origin/repos/CentOS-OpenShift-Origin.repo

@@ -3,26 +3,25 @@ name=CentOS OpenShift Origin
 baseurl=http://mirror.centos.org/centos/7/paas/x86_64/openshift-origin/
 enabled=1
 gpgcheck=1
-gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-PaaS
+gpgkey=file:///etc/pki/rpm-gpg/openshift-ansible-CentOS-SIG-PaaS
 
 [centos-openshift-origin-testing]
 name=CentOS OpenShift Origin Testing
 baseurl=http://buildlogs.centos.org/centos/7/paas/x86_64/openshift-origin/
 enabled=0
 gpgcheck=0
-gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-PaaS
+gpgkey=file:///etc/pki/rpm-gpg/openshift-ansible-CentOS-SIG-PaaS
 
 [centos-openshift-origin-debuginfo]
 name=CentOS OpenShift Origin DebugInfo
 baseurl=http://debuginfo.centos.org/centos/7/paas/x86_64/
 enabled=0
 gpgcheck=1
-gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-PaaS
+gpgkey=file:///etc/pki/rpm-gpg/openshift-ansible-CentOS-SIG-PaaS
 
 [centos-openshift-origin-source]
 name=CentOS OpenShift Origin Source
 baseurl=http://vault.centos.org/centos/7/paas/Source/openshift-origin/
 enabled=0
 gpgcheck=1
-gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-PaaS
-
+gpgkey=file:///etc/pki/rpm-gpg/openshift-ansible-CentOS-SIG-PaaS

+ 0 - 20
roles/openshift_repos/tasks/centos_sig.yaml

@@ -1,20 +0,0 @@
----
-- name: Install CentOS OpenShift Origin Repo on RHEL
-  copy:
-    src: rhel-origin/repos/CentOS-OpenShift-Origin.repo
-    dest: /etc/yum.repos.d/CentOS-OpenShift-Origin.repo
-  when: ansible_distribution != 'CentOS'
-
-- name: Install CentOS extras gpg key for RHEL
-  copy:
-    src: rhel-origin/RPM-GPG-KEY-CentOS-SIG-PaaS
-    dest: /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-PaaS
-    mode: 0644
-  when: ansible_distribution != 'CentOS'
-
-- name: Install the CentOS PaaS SIG release packages
-  action: "{{ ansible_pkg_mgr }} name={{ item }} state=present"
-  with_items:
-  - centos-release-paas-common
-  - centos-release-openshift-origin
-  when: ansible_distribution == 'CentOS'

+ 0 - 4
roles/openshift_repos/tasks/main.yaml

@@ -78,7 +78,3 @@
   - "fedora-{{ openshift_deployment_type }}/repos/*"
   notify: refresh cache
   when: (ansible_distribution == "Fedora") and not openshift.common.is_containerized | bool
-
-- name: Configure the CentOS PaaS SIG repos if needed
-  include: centos_sig.yaml
-  when: not openshift.common.is_containerized | bool and deployment_type == 'origin' and ansible_distribution != 'Fedora'

+ 3 - 3
roles/openshift_serviceaccounts/tasks/main.yml

@@ -24,11 +24,11 @@
   register: scc_test
   with_items: "{{ openshift_serviceaccounts_sccs }}"
 
-- name: Grant the user access to the privileged scc
+- name: Grant the user access to the appropriate scc
   command: >
       {{ openshift.common.admin_binary }} policy add-scc-to-user
-      privileged system:serviceaccount:{{ openshift_serviceaccounts_namespace }}:{{ item.0 }}
-  when: "openshift.common.version_gte_3_1_or_1_1 and item.1.rc == 0 and 'system:serviceaccount:{{ openshift_serviceaccounts_namespace }}:{{ item.0 }}' not in {{ (item.1.stdout | from_yaml).users }}"
+      {{ item.1.item }} system:serviceaccount:{{ openshift_serviceaccounts_namespace }}:{{ item.0 }}
+  when: "openshift.common.version_gte_3_1_or_1_1 and item.1.rc == 0 and 'system:serviceaccount:{{ openshift_serviceaccounts_namespace }}:{{ item.0 }}' not in {{ (item.1.stdout | from_yaml).users | default([]) }}"
   with_nested:
   - "{{ openshift_serviceaccounts_names }}"
   - "{{ scc_test.results }}"

+ 1 - 0
roles/openshift_storage_nfs/README.md

@@ -15,6 +15,7 @@ Role Variables
 --------------
 
 From this role:
+
 | Name                                            | Default value         |                                                             |
 |-------------------------------------------------|-----------------------|-------------------------------------------------------------|
 | openshift_hosted_registry_storage_nfs_directory | /exports              | Root export directory.                                      |

+ 1 - 0
roles/openshift_storage_nfs_lvm/meta/main.yml

@@ -14,3 +14,4 @@ galaxy_info:
     - all
   categories:
     - openshift
+dependencies: []

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

@@ -1,2 +1,2 @@
 dependencies:
-  - openshift_facts
+- role: openshift_facts

+ 10 - 4
utils/src/ooinstall/variants.py

@@ -33,7 +33,7 @@ class Variant(object):
         return self.versions[0]
 
 
-# WARNING: Keep the versions ordered, most recent last:
+# WARNING: Keep the versions ordered, most recent first:
 OSE = Variant('openshift-enterprise', 'OpenShift Enterprise',
     [
         Version('3.2', 'openshift-enterprise'),
@@ -49,9 +49,15 @@ AEP = Variant('atomic-enterprise', 'Atomic Enterprise Platform',
     ]
 )
 
-# Ordered list of variants we can install, first is the default.
-SUPPORTED_VARIANTS = (OSE, AEP)
+origin = Variant('origin', 'OpenShift Origin',
+    [
+        Version('1.2', 'origin'),
+    ]
+)
 
+# Ordered list of variants we can install, first is the default.
+SUPPORTED_VARIANTS = (OSE, AEP, origin)
+DISPLAY_VARIANTS = (OSE, AEP)
 
 def find_variant(name, version=None):
     """
@@ -72,7 +78,7 @@ def find_variant(name, version=None):
 
 def get_variant_version_combos():
     combos = []
-    for variant in SUPPORTED_VARIANTS:
+    for variant in DISPLAY_VARIANTS:
         for ver in variant.versions:
             combos.append((variant, ver))
     return combos