summaryrefslogtreecommitdiffstats
path: root/roles
diff options
context:
space:
mode:
Diffstat (limited to 'roles')
-rw-r--r--roles/ansible_service_broker/tasks/install.yml17
-rw-r--r--roles/calico_master/tasks/main.yml2
-rw-r--r--roles/container_runtime/defaults/main.yml39
-rw-r--r--roles/container_runtime/tasks/package_docker.yml11
-rw-r--r--roles/etcd/tasks/auxiliary/drop_etcdctl.yml2
-rw-r--r--roles/flannel/meta/main.yml1
-rw-r--r--roles/kuryr/tasks/node.yaml2
-rw-r--r--roles/kuryr/templates/cni-daemonset.yaml.j219
-rw-r--r--roles/kuryr/templates/configmap.yaml.j2357
-rw-r--r--roles/lib_utils/filter_plugins/oo_filters.py25
-rw-r--r--roles/lib_utils/filter_plugins/openshift_master.py6
-rw-r--r--roles/lib_utils/library/docker_creds.py4
-rw-r--r--roles/openshift_aws/defaults/main.yml14
-rw-r--r--roles/openshift_aws/tasks/accept_nodes.yml4
-rw-r--r--roles/openshift_aws/tasks/elb.yml2
-rw-r--r--roles/openshift_aws/tasks/provision.yml17
-rw-r--r--roles/openshift_aws/tasks/provision_elb.yml15
-rw-r--r--roles/openshift_aws/tasks/provision_nodes.yml17
-rw-r--r--roles/openshift_aws/tasks/uninstall_security_group.yml14
-rw-r--r--roles/openshift_aws/tasks/uninstall_ssh_keys.yml9
-rw-r--r--roles/openshift_aws/tasks/uninstall_vpc.yml36
-rw-r--r--roles/openshift_bootstrap_autoapprover/files/openshift-bootstrap-controller-policy.yaml10
-rw-r--r--roles/openshift_bootstrap_autoapprover/files/openshift-bootstrap-controller-role.yaml21
-rw-r--r--roles/openshift_bootstrap_autoapprover/files/openshift-bootstrap-controller-serviceaccount.yaml5
-rw-r--r--roles/openshift_bootstrap_autoapprover/files/openshift-bootstrap-controller.yaml68
-rw-r--r--roles/openshift_bootstrap_autoapprover/tasks/main.yml28
-rw-r--r--roles/openshift_ca/tasks/main.yml3
-rw-r--r--roles/openshift_cloud_provider/tasks/gce.yml10
-rw-r--r--roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-backup-job.yaml28
-rw-r--r--roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-backup-pvc.yaml10
-rw-r--r--roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-pv-backup-example.yaml13
-rw-r--r--roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-pv-db-example.yaml45
-rw-r--r--roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-pv-region-example.yaml13
-rw-r--r--roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-pv-server-example.yaml45
-rw-r--r--roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-restore-job.yaml35
-rw-r--r--roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-scc-sysadmin.yaml38
-rw-r--r--roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-template-ext-db.yaml956
-rw-r--r--roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-template.yaml1424
-rw-r--r--roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-backup-job.yaml28
-rw-r--r--roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-backup-pvc.yaml10
-rw-r--r--roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-pv-backup-example.yaml13
-rw-r--r--roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-pv-db-example.yaml45
-rw-r--r--roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-pv-region-example.yaml13
-rw-r--r--roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-pv-server-example.yaml45
-rw-r--r--roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-restore-job.yaml35
-rw-r--r--roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-scc-sysadmin.yaml38
-rw-r--r--roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-template-ext-db.yaml956
-rw-r--r--roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-template.yaml1424
-rw-r--r--roles/openshift_examples/meta/main.yml1
-rw-r--r--roles/openshift_excluder/tasks/verify_excluder.yml2
-rw-r--r--roles/openshift_expand_partition/tasks/main.yml2
-rwxr-xr-xroles/openshift_facts/library/openshift_facts.py5
-rw-r--r--roles/openshift_gcp/files/bootstrap-script.sh42
-rw-r--r--roles/openshift_gcp/files/openshift-bootstrap-update.service7
-rw-r--r--roles/openshift_gcp/files/openshift-bootstrap-update.timer10
-rw-r--r--roles/openshift_gcp/files/partition.conf (renamed from roles/openshift_gcp_image_prep/files/partition.conf)2
-rw-r--r--roles/openshift_gcp/meta/main.yml17
-rw-r--r--roles/openshift_gcp/tasks/add_custom_repositories.yml20
-rw-r--r--roles/openshift_gcp/tasks/configure_gcp_base_image.yml (renamed from roles/openshift_gcp_image_prep/tasks/main.yaml)14
-rw-r--r--roles/openshift_gcp/tasks/configure_master_bootstrap.yml36
-rw-r--r--roles/openshift_gcp/tasks/configure_master_healthcheck.yml19
-rw-r--r--roles/openshift_gcp/tasks/dynamic_inventory.yml5
-rw-r--r--roles/openshift_gcp/tasks/frequent_log_rotation.yml18
-rw-r--r--roles/openshift_gcp/tasks/main.yml (renamed from roles/openshift_gcp/tasks/main.yaml)4
-rw-r--r--roles/openshift_gcp/tasks/node_cloud_config.yml12
-rw-r--r--roles/openshift_gcp/tasks/publish_image.yml32
-rw-r--r--roles/openshift_gcp/tasks/setup_scale_group_facts.yml44
-rw-r--r--roles/openshift_gcp/templates/inventory.j2.sh8
-rw-r--r--roles/openshift_gcp/templates/master_healthcheck.j268
-rw-r--r--roles/openshift_gcp/templates/openshift-bootstrap-update.j27
-rw-r--r--roles/openshift_gcp/templates/provision.j2.sh17
-rw-r--r--roles/openshift_gcp/templates/yum_repo.j220
-rw-r--r--roles/openshift_grafana/defaults/main.yml12
-rw-r--r--roles/openshift_grafana/files/grafana-ocp-oauth.yml661
-rw-r--r--roles/openshift_grafana/files/grafana-ocp.yml76
-rw-r--r--roles/openshift_grafana/files/openshift-cluster-monitoring.json5138
-rw-r--r--roles/openshift_grafana/meta/main.yml13
-rw-r--r--roles/openshift_grafana/tasks/gf-permissions.yml12
-rw-r--r--roles/openshift_grafana/tasks/main.yml122
-rw-r--r--roles/openshift_health_checker/openshift_checks/__init__.py43
-rw-r--r--roles/openshift_health_checker/openshift_checks/docker_image_availability.py34
-rw-r--r--roles/openshift_health_checker/openshift_checks/logging/elasticsearch.py2
-rw-r--r--roles/openshift_health_checker/openshift_checks/logging/kibana.py13
-rw-r--r--roles/openshift_health_checker/openshift_checks/ovs_version.py27
-rw-r--r--roles/openshift_health_checker/openshift_checks/package_version.py58
-rw-r--r--roles/openshift_health_checker/test/kibana_test.py12
-rw-r--r--roles/openshift_health_checker/test/ovs_version_test.py23
-rw-r--r--roles/openshift_health_checker/test/package_version_test.py5
-rw-r--r--roles/openshift_hosted/tasks/storage/glusterfs_endpoints.yml13
l---------roles/openshift_hosted/tasks/storage/registry_config.j21
-rw-r--r--roles/openshift_hosted_templates/files/v3.6/enterprise/registry-console.yaml2
-rw-r--r--roles/openshift_hosted_templates/files/v3.7/enterprise/registry-console.yaml2
-rw-r--r--roles/openshift_hosted_templates/files/v3.8/enterprise/registry-console.yaml2
-rw-r--r--roles/openshift_hosted_templates/files/v3.9/enterprise/registry-console.yaml2
-rw-r--r--roles/openshift_loadbalancer/templates/haproxy.cfg.j23
-rw-r--r--roles/openshift_logging/tasks/annotate_ops_projects.yaml1
-rw-r--r--roles/openshift_logging/tasks/delete_logging.yaml10
-rw-r--r--roles/openshift_logging/tasks/generate_certs.yaml2
-rw-r--r--roles/openshift_logging/tasks/install_logging.yaml14
-rw-r--r--roles/openshift_logging/tasks/procure_server_certs.yaml2
-rw-r--r--roles/openshift_logging_elasticsearch/tasks/get_es_version.yml4
-rw-r--r--roles/openshift_logging_elasticsearch/tasks/restart_cluster.yml4
-rw-r--r--roles/openshift_management/files/templates/cloudforms/cfme-backup-job.yaml2
-rw-r--r--roles/openshift_management/files/templates/cloudforms/cfme-restore-job.yaml2
-rw-r--r--roles/openshift_management/files/templates/cloudforms/cfme-template-ext-db.yaml219
-rw-r--r--roles/openshift_management/files/templates/cloudforms/cfme-template.yaml221
-rw-r--r--roles/openshift_master/tasks/upgrade/rpm_upgrade.yml23
-rw-r--r--roles/openshift_metrics/tasks/install_metrics.yaml6
-rw-r--r--roles/openshift_metrics/tasks/oc_apply.yaml4
-rw-r--r--roles/openshift_metrics/tasks/uninstall_metrics.yaml10
-rw-r--r--roles/openshift_node/defaults/main.yml18
-rw-r--r--roles/openshift_node/tasks/node_system_container.yml19
-rw-r--r--roles/openshift_node/tasks/upgrade/config_changes.yml6
-rw-r--r--roles/openshift_node/templates/node.yaml.v1.j22
-rw-r--r--roles/openshift_node_certificates/tasks/main.yml20
-rw-r--r--roles/openshift_node_certificates/vars/main.yml2
-rw-r--r--roles/openshift_openstack/templates/heat_stack.yaml.j224
-rw-r--r--roles/openshift_openstack/templates/heat_stack_server.yaml.j22
-rw-r--r--roles/openshift_persistent_volumes/tasks/pv.yml2
-rw-r--r--roles/openshift_persistent_volumes/tasks/pvc.yml2
-rw-r--r--roles/openshift_provisioners/tasks/oc_apply.yaml6
-rw-r--r--roles/openshift_service_catalog/defaults/main.yml1
-rw-r--r--roles/openshift_service_catalog/templates/controller_manager.j26
-rw-r--r--roles/openshift_version/tasks/check_available_rpms.yml2
-rw-r--r--roles/openshift_version/tasks/first_master_containerized_version.yml5
-rw-r--r--roles/openshift_version/tasks/first_master_rpm_version.yml6
-rw-r--r--roles/openshift_version/tasks/masters_and_nodes.yml7
-rw-r--r--roles/openshift_web_console/defaults/main.yml3
-rw-r--r--roles/openshift_web_console/tasks/install.yml114
-rw-r--r--roles/openshift_web_console/tasks/rollout_console.yml20
-rw-r--r--roles/openshift_web_console/tasks/update_asset_config.yml68
-rw-r--r--roles/openshift_web_console/tasks/update_console_config.yml67
-rw-r--r--roles/openshift_web_console/vars/default_images.yml4
-rw-r--r--roles/openshift_web_console/vars/main.yml1
-rw-r--r--roles/openshift_web_console/vars/openshift-enterprise.yml4
-rw-r--r--roles/os_firewall/tasks/firewalld.yml5
-rw-r--r--roles/template_service_broker/defaults/main.yml2
-rw-r--r--roles/template_service_broker/tasks/install.yml21
-rw-r--r--roles/template_service_broker/tasks/remove.yml15
-rw-r--r--roles/template_service_broker/vars/default_images.yml4
-rw-r--r--roles/template_service_broker/vars/openshift-enterprise.yml4
-rw-r--r--roles/tuned/tasks/main.yml7
142 files changed, 12298 insertions, 1355 deletions
diff --git a/roles/ansible_service_broker/tasks/install.yml b/roles/ansible_service_broker/tasks/install.yml
index ba2f7293b..f869b5fae 100644
--- a/roles/ansible_service_broker/tasks/install.yml
+++ b/roles/ansible_service_broker/tasks/install.yml
@@ -72,6 +72,15 @@
- apiGroups: ["image.openshift.io", ""]
resources: ["images"]
verbs: ["get", "list"]
+ - apiGroups: ["network.openshift.io"]
+ resources: ["clusternetworks", "netnamespaces"]
+ verbs: ["get"]
+ - apiGroups: ["network.openshift.io"]
+ resources: ["netnamespaces"]
+ verbs: ["update"]
+ - apiGroups: ["networking.k8s.io"]
+ resources: ["networkpolicies"]
+ verbs: ["create", "delete"]
- name: Create asb-access cluster role
oc_clusterrole:
@@ -366,6 +375,11 @@
secret:
secretName: etcd-auth-secret
+- name: set auth name and type facts if needed
+ set_fact:
+ ansible_service_broker_registry_auth_type: "secret"
+ ansible_service_broker_registry_auth_name: "asb-registry-auth"
+ when: ansible_service_broker_registry_user != "" and ansible_service_broker_registry_password != ""
# TODO: saw a oc_configmap in the library, but didn't understand how to get it to do the following:
- name: Create config map for ansible-service-broker
@@ -393,6 +407,8 @@
org: {{ ansible_service_broker_registry_organization }}
tag: {{ ansible_service_broker_registry_tag }}
white_list: {{ ansible_service_broker_registry_whitelist | to_yaml }}
+ auth_type: "{{ ansible_service_broker_registry_auth_type | default("") }}"
+ auth_name: "{{ ansible_service_broker_registry_auth_name | default("") }}"
- type: local_openshift
name: localregistry
namespaces: ['openshift']
@@ -438,6 +454,7 @@
data: "{{ ansible_service_broker_registry_user }}"
- path: password
data: "{{ ansible_service_broker_registry_password }}"
+ when: ansible_service_broker_registry_user != "" and ansible_service_broker_registry_password != ""
- name: Create the Broker resource in the catalog
oc_obj:
diff --git a/roles/calico_master/tasks/main.yml b/roles/calico_master/tasks/main.yml
index 05415a4d6..834ebba64 100644
--- a/roles/calico_master/tasks/main.yml
+++ b/roles/calico_master/tasks/main.yml
@@ -23,7 +23,7 @@
-f {{ mktemp.stdout }}/calico-policy-controller.yml
--config={{ openshift.common.config_base }}/master/admin.kubeconfig
register: calico_create_output
- failed_when: ('already exists' not in calico_create_output.stderr) and ('created' not in calico_create_output.stdout)
+ failed_when: "('already exists' not in calico_create_output.stderr) and ('created' not in calico_create_output.stdout) and calico_create_output.rc != 0"
changed_when: ('created' in calico_create_output.stdout)
- name: Calico Master | Delete temp directory
diff --git a/roles/container_runtime/defaults/main.yml b/roles/container_runtime/defaults/main.yml
index d0e37e2f4..8203d15f5 100644
--- a/roles/container_runtime/defaults/main.yml
+++ b/roles/container_runtime/defaults/main.yml
@@ -101,45 +101,34 @@ l_crt_crio_image_tag_dict:
openshift-enterprise: "{{ l_openshift_image_tag }}"
origin: "{{ openshift_crio_image_tag | default(openshift_crio_image_tag_default) }}"
-l_crt_crio_image_prepend_dict:
- openshift-enterprise: "registry.access.redhat.com/openshift3"
- origin: "docker.io/gscrivano"
-
l_crt_crio_image_dict:
- Fedora:
- crio_image_name: "cri-o-fedora"
- crio_image_tag: "latest"
- CentOS:
- crio_image_name: "cri-o-centos"
- crio_image_tag: "latest"
- RedHat:
- crio_image_name: "cri-o"
- crio_image_tag: "{{ openshift_crio_image_tag | default(l_crt_crio_image_tag_dict[openshift_deployment_type]) }}"
-
-l_crio_image_prepend: "{{ l_crt_crio_image_prepend_dict[openshift_deployment_type] }}"
-l_crio_image_name: "{{ l_crt_crio_image_dict[ansible_distribution]['crio_image_name'] }}"
-l_crio_image_tag: "{{ l_crt_crio_image_dict[ansible_distribution] }}"
-
-l_crio_image_default: "{{ l_crio_image_prepend }}/{{ l_crio_image_name }}:{{ l_crio_image_tag }}"
+ Fedora: "registry.fedoraproject.org/latest/cri-o"
+ CentOS: "registry.centos.org/projectatomic/cri-o"
+ RedHat: "registry.access.redhat.com/openshift3/cri-o"
+
+l_crio_image_name: "{{ l_crt_crio_image_dict[ansible_distribution] }}"
+l_crio_image_tag: "{{ l_crt_crio_image_tag_dict[openshift_deployment_type] }}"
+
+l_crio_image_default: "{{ l_crio_image_name }}:{{ l_crio_image_tag }}"
l_crio_image: "{{ openshift_crio_systemcontainer_image_override | default(l_crio_image_default) }}"
# ----------------------- #
# systemcontainers_docker #
# ----------------------- #
-l_crt_docker_image_prepend_dict:
- Fedora: "registry.fedoraproject.org/latest"
- Centos: "docker.io/gscrivano"
- RedHat: "registry.access.redhat.com/openshift3"
+l_crt_docker_image_dict:
+ Fedora: "registry.fedoraproject.org/latest/docker"
+ Centos: "registry.centos.org/projectatomic/docker"
+ RedHat: "registry.access.redhat.com/openshift3/container-engine"
openshift_docker_image_tag_default: "latest"
l_crt_docker_image_tag_dict:
openshift-enterprise: "{{ l_openshift_image_tag }}"
origin: "{{ openshift_docker_image_tag | default(openshift_docker_image_tag_default) }}"
-l_docker_image_prepend: "{{ l_crt_docker_image_prepend_dict[ansible_distribution] }}"
+l_docker_image_prepend: "{{ l_crt_docker_image_dict[ansible_distribution] }}"
l_docker_image_tag: "{{ l_crt_docker_image_tag_dict[openshift_deployment_type] }}"
-l_docker_image_default: "{{ l_docker_image_prepend }}/{{ openshift_docker_service_name }}:{{ l_docker_image_tag }}"
+l_docker_image_default: "{{ l_docker_image_prepend }}:{{ l_docker_image_tag }}"
l_docker_image: "{{ openshift_docker_systemcontainer_image_override | default(l_docker_image_default) }}"
l_is_node_system_container: "{{ (openshift_use_node_system_container | default(openshift_use_system_containers | default(false)) | bool) }}"
diff --git a/roles/container_runtime/tasks/package_docker.yml b/roles/container_runtime/tasks/package_docker.yml
index d6e7e7fed..ed9a2709b 100644
--- a/roles/container_runtime/tasks/package_docker.yml
+++ b/roles/container_runtime/tasks/package_docker.yml
@@ -1,6 +1,17 @@
---
- include_tasks: common/pre.yml
+# In some cases, some services may be run as containers and docker may still
+# be installed via rpm.
+- include_tasks: common/atomic_proxy.yml
+ when:
+ - >
+ (openshift_use_system_containers | default(False)) | bool
+ or (openshift_use_etcd_system_container | default(False)) | bool
+ or (openshift_use_openvswitch_system_container | default(False)) | bool
+ or (openshift_use_node_system_container | default(False)) | bool
+ or (openshift_use_master_system_container | default(False)) | bool
+
- name: Get current installed Docker version
command: "{{ repoquery_installed }} --qf '%{version}' docker"
when: not openshift_is_atomic | bool
diff --git a/roles/etcd/tasks/auxiliary/drop_etcdctl.yml b/roles/etcd/tasks/auxiliary/drop_etcdctl.yml
index 881a8c270..cab835e20 100644
--- a/roles/etcd/tasks/auxiliary/drop_etcdctl.yml
+++ b/roles/etcd/tasks/auxiliary/drop_etcdctl.yml
@@ -1,7 +1,7 @@
---
- name: Install etcd for etcdctl
package: name=etcd{{ '-' + etcd_version if etcd_version is defined else '' }} state=present
- when: not openshift_is_atomic | bool
+ when: not openshift_is_containerized | bool
register: result
until: result is succeeded
diff --git a/roles/flannel/meta/main.yml b/roles/flannel/meta/main.yml
index 7634b8192..38d2f748b 100644
--- a/roles/flannel/meta/main.yml
+++ b/roles/flannel/meta/main.yml
@@ -14,3 +14,4 @@ galaxy_info:
- system
dependencies:
- role: lib_utils
+- role: openshift_facts
diff --git a/roles/kuryr/tasks/node.yaml b/roles/kuryr/tasks/node.yaml
index 08f2d5adc..41d0ead20 100644
--- a/roles/kuryr/tasks/node.yaml
+++ b/roles/kuryr/tasks/node.yaml
@@ -40,7 +40,7 @@
regexp: '^OPTIONS="?(.*?)"?$'
backrefs: yes
backup: yes
- line: 'OPTIONS="\1 --disable dns,proxy,plugins"'
+ line: 'OPTIONS="\1 --disable proxy"'
- name: force node restart to disable the proxy
service:
diff --git a/roles/kuryr/templates/cni-daemonset.yaml.j2 b/roles/kuryr/templates/cni-daemonset.yaml.j2
index 39348ae90..09f4c7dfe 100644
--- a/roles/kuryr/templates/cni-daemonset.yaml.j2
+++ b/roles/kuryr/templates/cni-daemonset.yaml.j2
@@ -26,6 +26,13 @@ spec:
image: kuryr/cni:latest
imagePullPolicy: IfNotPresent
command: [ "cni_ds_init" ]
+ env:
+ - name: CNI_DAEMON
+ value: "True"
+ - name: KUBERNETES_NODE_NAME
+ valueFrom:
+ fieldRef:
+ fieldPath: spec.nodeName
securityContext:
privileged: true
volumeMounts:
@@ -38,6 +45,10 @@ spec:
subPath: kuryr-cni.conf
- name: etc
mountPath: /etc
+ - name: proc
+ mountPath: /host_proc
+ - name: openvswitch
+ mountPath: /var/run/openvswitch
volumes:
- name: bin
hostPath:
@@ -50,4 +61,10 @@ spec:
name: kuryr-config
- name: etc
hostPath:
- path: /etc \ No newline at end of file
+ path: /etc
+ - name: proc
+ hostPath:
+ path: /proc
+ - name: openvswitch
+ hostPath:
+ path: /var/run/openvswitch
diff --git a/roles/kuryr/templates/configmap.yaml.j2 b/roles/kuryr/templates/configmap.yaml.j2
index 96c215f00..4bf1dbddf 100644
--- a/roles/kuryr/templates/configmap.yaml.j2
+++ b/roles/kuryr/templates/configmap.yaml.j2
@@ -16,17 +16,17 @@ data:
# Directory for Kuryr vif binding executables. (string value)
#bindir = /usr/libexec/kuryr
+ # Neutron subnetpool name will be prefixed by this. (string value)
+ #subnetpool_name_prefix = kuryrPool
+
+ # baremetal or nested-containers are the supported values. (string value)
+ #deployment_type = baremetal
+
# If set to true, the logging level will be set to DEBUG instead of the default
# INFO level. (boolean value)
# Note: This option can be changed without restarting.
#debug = false
- # DEPRECATED: If set to false, the logging level will be set to WARNING instead
- # of the default INFO level. (boolean value)
- # This option is deprecated for removal.
- # Its value may be silently ignored in the future.
- #verbose = true
-
# The name of a logging configuration file. This file is appended to any
# existing logging configuration files. For details about logging configuration
# files, see the Python logging module documentation. Note that when logging
@@ -46,7 +46,7 @@ data:
# logging will go to stderr as defined by use_stderr. This option is ignored if
# log_config_append is set. (string value)
# Deprecated group/name - [DEFAULT]/logfile
- #log_file = /var/log/kuryr/kuryr-controller.log
+ #log_file = <None>
# (Optional) The base directory used for relative log_file paths. This option
# is ignored if log_config_append is set. (string value)
@@ -65,13 +65,19 @@ data:
# is set. (boolean value)
#use_syslog = false
+ # Enable journald for logging. If running in a systemd environment you may wish
+ # to enable journal support. Doing so will use the journal native protocol
+ # which includes structured metadata in addition to log messages.This option is
+ # ignored if log_config_append is set. (boolean value)
+ #use_journal = false
+
# Syslog facility to receive log lines. This option is ignored if
# log_config_append is set. (string value)
#syslog_log_facility = LOG_USER
# Log output to standard error. This option is ignored if log_config_append is
# set. (boolean value)
- #use_stderr = true
+ #use_stderr = false
# Format string to use for log messages with context. (string value)
#logging_context_format_string = %(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [%(request_id)s %(user_identity)s] %(instance)s%(message)s
@@ -93,7 +99,7 @@ data:
# List of package logging levels in logger=LEVEL pairs. This option is ignored
# if log_config_append is set. (list value)
- #default_log_levels = amqp=WARN,amqplib=WARN,boto=WARN,qpid=WARN,sqlalchemy=WARN,suds=INFO,oslo.messaging=INFO,iso8601=WARN,requests.packages.urllib3.connectionpool=WARN,urllib3.connectionpool=WARN,websocket=WARN,requests.packages.urllib3.util.retry=WARN,urllib3.util.retry=WARN,keystonemiddleware=WARN,routes.middleware=WARN,stevedore=WARN,taskflow=WARN,keystoneauth=WARN,oslo.cache=INFO,dogpile.core.dogpile=INFO
+ #default_log_levels = amqp=WARN,amqplib=WARN,boto=WARN,qpid=WARN,sqlalchemy=WARN,suds=INFO,oslo.messaging=INFO,oslo_messaging=INFO,iso8601=WARN,requests.packages.urllib3.connectionpool=WARN,urllib3.connectionpool=WARN,websocket=WARN,requests.packages.urllib3.util.retry=WARN,urllib3.util.retry=WARN,keystonemiddleware=WARN,routes.middleware=WARN,stevedore=WARN,taskflow=WARN,keystoneauth=WARN,oslo.cache=INFO,dogpile.core.dogpile=INFO
# Enables or disables publication of error events. (boolean value)
#publish_errors = false
@@ -106,15 +112,86 @@ data:
# value)
#instance_uuid_format = "[instance: %(uuid)s] "
+ # Interval, number of seconds, of log rate limiting. (integer value)
+ #rate_limit_interval = 0
+
+ # Maximum number of logged messages per rate_limit_interval. (integer value)
+ #rate_limit_burst = 0
+
+ # Log level name used by rate limiting: CRITICAL, ERROR, INFO, WARNING, DEBUG
+ # or empty string. Logs with level greater or equal to rate_limit_except_level
+ # are not filtered. An empty string means that all levels are filtered. (string
+ # value)
+ #rate_limit_except_level = CRITICAL
+
# Enables or disables fatal status of deprecations. (boolean value)
#fatal_deprecations = false
[binding]
+ # Configuration options for container interface binding.
- driver = kuryr.lib.binding.drivers.vlan
+ #
+ # From kuryr_kubernetes
+ #
+
+ # The name prefix of the veth endpoint put inside the container. (string value)
+ #veth_dst_prefix = eth
+
+ # Driver to use for binding and unbinding ports. (string value)
+ # Deprecated group/name - [binding]/driver
+ #default_driver = kuryr.lib.binding.drivers.veth
+
+ # Drivers to use for binding and unbinding ports. (list value)
+ #enabled_drivers = kuryr.lib.binding.drivers.veth
+
+ # Specifies the name of the Nova instance interface to link the virtual devices
+ # to (only applicable to some binding drivers. (string value)
link_iface = eth0
+ driver = kuryr.lib.binding.drivers.vlan
+
+
+ [cni_daemon]
+
+ #
+ # From kuryr_kubernetes
+ #
+
+ # Enable CNI Daemon configuration. (boolean value)
+ daemon_enabled = true
+
+ # Bind address for CNI daemon HTTP server. It is recommened to allow only local
+ # connections. (string value)
+ bind_address = 127.0.0.1:50036
+
+ # Maximum number of processes that will be spawned to process requests from CNI
+ # driver. (integer value)
+ #worker_num = 30
+
+ # Time (in seconds) the CNI daemon will wait for VIF annotation to appear in
+ # pod metadata before failing the CNI request. (integer value)
+ #vif_annotation_timeout = 120
+
+ # Kuryr uses pyroute2 library to manipulate networking interfaces. When
+ # processing a high number of Kuryr requests in parallel, it may take kernel
+ # more time to process all networking stack changes. This option allows to tune
+ # internal pyroute2 timeout. (integer value)
+ #pyroute2_timeout = 30
+
+ # Set to True when you are running kuryr-daemon inside a Docker container on
+ # Kubernetes host. E.g. as DaemonSet on Kubernetes cluster Kuryr is supposed to
+ # provide networking for. This mainly means thatkuryr-daemon will look for
+ # network namespaces in $netns_proc_dir instead of /proc. (boolean value)
+ docker_mode = true
+
+ # When docker_mode is set to True, this config option should be set to where
+ # host's /proc directory is mounted. Please note that mounting it is necessary
+ # to allow Kuryr-Kubernetes to move host interfaces between host network
+ # namespaces, which is essential for Kuryr to work. (string value)
+ netns_proc_dir = /host_proc
+
+
[kubernetes]
#
@@ -164,11 +241,6 @@ data:
# The driver that manages VIFs pools for Kubernetes Pods (string value)
vif_pool_driver = {{ kuryr_openstack_enable_pools | default(False) | ternary('nested', 'noop') }}
- [vif_pool]
- ports_pool_max = {{ kuryr_openstack_pool_max | default(0) }}
- ports_pool_min = {{ kuryr_openstack_pool_min | default(1) }}
- ports_pool_batch = {{ kuryr_openstack_pool_batch | default(5) }}
- ports_pool_update_frequency = {{ kuryr_openstack_pool_update_frequency | default(20) }}
[neutron]
# Configuration options for OpenStack Neutron
@@ -232,13 +304,55 @@ data:
external_svc_subnet = {{ kuryr_openstack_external_svc_subnet_id }}
[pod_vif_nested]
+
worker_nodes_subnet = {{ kuryr_openstack_worker_nodes_subnet_id }}
+
+
+ [pool_manager]
+
+ #
+ # From kuryr_kubernetes
+ #
+
+ # Absolute path to socket file that will be used for communication with the
+ # Pool Manager daemon (string value)
+ #sock_file = /run/kuryr/kuryr_manage.sock
+
+
+ [vif_pool]
+
+ #
+ # From kuryr_kubernetes
+ #
+
+ # Set a maximun amount of ports per pool. 0 to disable (integer value)
+ ports_pool_max = {{ kuryr_openstack_pool_max | default(0) }}
+
+ # Set a target minimum size of the pool of ports (integer value)
+ ports_pool_min = {{ kuryr_openstack_pool_min | default(1) }}
+
+ # Number of ports to be created in a bulk request (integer value)
+ ports_pool_batch = {{ kuryr_openstack_pool_batch | default(5) }}
+
+ # Minimun interval (in seconds) between pool updates (integer value)
+ ports_pool_update_frequency = {{ kuryr_openstack_pool_update_frequency | default(20) }}
+
kuryr-cni.conf: |+
[DEFAULT]
#
# From kuryr_kubernetes
#
+
+ # Directory for Kuryr vif binding executables. (string value)
+ #bindir = /usr/libexec/kuryr
+
+ # Neutron subnetpool name will be prefixed by this. (string value)
+ #subnetpool_name_prefix = kuryrPool
+
+ # baremetal or nested-containers are the supported values. (string value)
+ #deployment_type = baremetal
+
# If set to true, the logging level will be set to DEBUG instead of the default
# INFO level. (boolean value)
# Note: This option can be changed without restarting.
@@ -263,7 +377,7 @@ data:
# logging will go to stderr as defined by use_stderr. This option is ignored if
# log_config_append is set. (string value)
# Deprecated group/name - [DEFAULT]/logfile
- #log_file = /var/log/kuryr/cni.log
+ #log_file = <None>
# (Optional) The base directory used for relative log_file paths. This option
# is ignored if log_config_append is set. (string value)
@@ -282,6 +396,12 @@ data:
# is set. (boolean value)
#use_syslog = false
+ # Enable journald for logging. If running in a systemd environment you may wish
+ # to enable journal support. Doing so will use the journal native protocol
+ # which includes structured metadata in addition to log messages.This option is
+ # ignored if log_config_append is set. (boolean value)
+ #use_journal = false
+
# Syslog facility to receive log lines. This option is ignored if
# log_config_append is set. (string value)
#syslog_log_facility = LOG_USER
@@ -310,7 +430,7 @@ data:
# List of package logging levels in logger=LEVEL pairs. This option is ignored
# if log_config_append is set. (list value)
- #default_log_levels = amqp=WARN,amqplib=WARN,boto=WARN,qpid=WARN,sqlalchemy=WARN,suds=INFO,oslo.messaging=INFO,iso8601=WARN,requests.packages.urllib3.connectionpool=WARN,urllib3.connectionpool=WARN,websocket=WARN,requests.packages.urllib3.util.retry=WARN,urllib3.util.retry=WARN,keystonemiddleware=WARN,routes.middleware=WARN,stevedore=WARN,taskflow=WARN,keystoneauth=WARN,oslo.cache=INFO,dogpile.core.dogpile=INFO
+ #default_log_levels = amqp=WARN,amqplib=WARN,boto=WARN,qpid=WARN,sqlalchemy=WARN,suds=INFO,oslo.messaging=INFO,oslo_messaging=INFO,iso8601=WARN,requests.packages.urllib3.connectionpool=WARN,urllib3.connectionpool=WARN,websocket=WARN,requests.packages.urllib3.util.retry=WARN,urllib3.util.retry=WARN,keystonemiddleware=WARN,routes.middleware=WARN,stevedore=WARN,taskflow=WARN,keystoneauth=WARN,oslo.cache=INFO,dogpile.core.dogpile=INFO
# Enables or disables publication of error events. (boolean value)
#publish_errors = false
@@ -323,14 +443,85 @@ data:
# value)
#instance_uuid_format = "[instance: %(uuid)s] "
+ # Interval, number of seconds, of log rate limiting. (integer value)
+ #rate_limit_interval = 0
+
+ # Maximum number of logged messages per rate_limit_interval. (integer value)
+ #rate_limit_burst = 0
+
+ # Log level name used by rate limiting: CRITICAL, ERROR, INFO, WARNING, DEBUG
+ # or empty string. Logs with level greater or equal to rate_limit_except_level
+ # are not filtered. An empty string means that all levels are filtered. (string
+ # value)
+ #rate_limit_except_level = CRITICAL
+
# Enables or disables fatal status of deprecations. (boolean value)
#fatal_deprecations = false
[binding]
+ # Configuration options for container interface binding.
+
+ #
+ # From kuryr_kubernetes
+ #
+
+ # The name prefix of the veth endpoint put inside the container. (string value)
+ #veth_dst_prefix = eth
+
+ # Driver to use for binding and unbinding ports. (string value)
+ # Deprecated group/name - [binding]/driver
+ #default_driver = kuryr.lib.binding.drivers.veth
+
+ # Drivers to use for binding and unbinding ports. (list value)
+ #enabled_drivers = kuryr.lib.binding.drivers.veth
+
+ # Specifies the name of the Nova instance interface to link the virtual devices
+ # to (only applicable to some binding drivers. (string value)
+ link_iface = eth0
driver = kuryr.lib.binding.drivers.vlan
- link_iface = {{ kuryr_cni_link_interface }}
+
+
+ [cni_daemon]
+
+ #
+ # From kuryr_kubernetes
+ #
+
+ # Enable CNI Daemon configuration. (boolean value)
+ daemon_enabled = true
+
+ # Bind address for CNI daemon HTTP server. It is recommened to allow only local
+ # connections. (string value)
+ bind_address = 127.0.0.1:50036
+
+ # Maximum number of processes that will be spawned to process requests from CNI
+ # driver. (integer value)
+ #worker_num = 30
+
+ # Time (in seconds) the CNI daemon will wait for VIF annotation to appear in
+ # pod metadata before failing the CNI request. (integer value)
+ #vif_annotation_timeout = 120
+
+ # Kuryr uses pyroute2 library to manipulate networking interfaces. When
+ # processing a high number of Kuryr requests in parallel, it may take kernel
+ # more time to process all networking stack changes. This option allows to tune
+ # internal pyroute2 timeout. (integer value)
+ #pyroute2_timeout = 30
+
+ # Set to True when you are running kuryr-daemon inside a Docker container on
+ # Kubernetes host. E.g. as DaemonSet on Kubernetes cluster Kuryr is supposed to
+ # provide networking for. This mainly means thatkuryr-daemon will look for
+ # network namespaces in $netns_proc_dir instead of /proc. (boolean value)
+ docker_mode = true
+
+ # When docker_mode is set to True, this config option should be set to where
+ # host's /proc directory is mounted. Please note that mounting it is necessary
+ # to allow Kuryr-Kubernetes to move host interfaces between host network
+ # namespaces, which is essential for Kuryr to work. (string value)
+ netns_proc_dir = /host_proc
+
[kubernetes]
@@ -341,12 +532,136 @@ data:
# The root URL of the Kubernetes API (string value)
api_root = {{ openshift.master.api_url }}
- # The token to talk to the k8s API
- token_file = /etc/kuryr/token
+ # Absolute path to client cert to connect to HTTPS K8S_API (string value)
+ # ssl_client_crt_file = /etc/kuryr/controller.crt
+
+ # Absolute path client key file to connect to HTTPS K8S_API (string value)
+ # ssl_client_key_file = /etc/kuryr/controller.key
# Absolute path to ca cert file to connect to HTTPS K8S_API (string value)
- ssl_ca_crt_file = /etc/kuryr/ca.crt
+ ssl_ca_crt_file = /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
+
+ # The token to talk to the k8s API
+ token_file = /var/run/secrets/kubernetes.io/serviceaccount/token
# HTTPS K8S_API server identity verification (boolean value)
# TODO (apuimedo): Make configurable
ssl_verify_server_crt = True
+
+ # The driver to determine OpenStack project for pod ports (string value)
+ pod_project_driver = default
+
+ # The driver to determine OpenStack project for services (string value)
+ service_project_driver = default
+
+ # The driver to determine Neutron subnets for pod ports (string value)
+ pod_subnets_driver = default
+
+ # The driver to determine Neutron subnets for services (string value)
+ service_subnets_driver = default
+
+ # The driver to determine Neutron security groups for pods (string value)
+ pod_security_groups_driver = default
+
+ # The driver to determine Neutron security groups for services (string value)
+ service_security_groups_driver = default
+
+ # The driver that provides VIFs for Kubernetes Pods. (string value)
+ pod_vif_driver = nested-vlan
+
+ # The driver that manages VIFs pools for Kubernetes Pods (string value)
+ vif_pool_driver = {{ kuryr_openstack_enable_pools | default(False) | ternary('nested', 'noop') }}
+
+ [neutron]
+ # Configuration options for OpenStack Neutron
+
+ #
+ # From kuryr_kubernetes
+ #
+
+ # Authentication URL (string value)
+ auth_url = {{ kuryr_openstack_auth_url }}
+
+ # Authentication type to load (string value)
+ # Deprecated group/name - [neutron]/auth_plugin
+ auth_type = password
+
+ # Domain ID to scope to (string value)
+ user_domain_name = {{ kuryr_openstack_user_domain_name }}
+
+ # User's password (string value)
+ password = {{ kuryr_openstack_password }}
+
+ # Domain name containing project (string value)
+ project_domain_name = {{ kuryr_openstack_project_domain_name }}
+
+ # Project ID to scope to (string value)
+ # Deprecated group/name - [neutron]/tenant-id
+ project_id = {{ kuryr_openstack_project_id }}
+
+ # Token (string value)
+ #token = <None>
+
+ # Trust ID (string value)
+ #trust_id = <None>
+
+ # User's domain id (string value)
+ #user_domain_id = <None>
+
+ # User id (string value)
+ #user_id = <None>
+
+ # Username (string value)
+ # Deprecated group/name - [neutron]/user-name
+ username = {{kuryr_openstack_username }}
+
+ # Whether a plugging operation is failed if the port to plug does not become
+ # active (boolean value)
+ #vif_plugging_is_fatal = false
+
+ # Seconds to wait for port to become active (integer value)
+ #vif_plugging_timeout = 0
+
+ [neutron_defaults]
+
+ pod_security_groups = {{ kuryr_openstack_pod_sg_id }}
+ pod_subnet = {{ kuryr_openstack_pod_subnet_id }}
+ service_subnet = {{ kuryr_openstack_service_subnet_id }}
+ project = {{ kuryr_openstack_pod_project_id }}
+ # TODO (apuimedo): Remove the duplicated line just after this one once the
+ # RDO packaging contains the upstream patch
+ worker_nodes_subnet = {{ kuryr_openstack_worker_nodes_subnet_id }}
+
+ [pod_vif_nested]
+
+ worker_nodes_subnet = {{ kuryr_openstack_worker_nodes_subnet_id }}
+
+
+ [pool_manager]
+
+ #
+ # From kuryr_kubernetes
+ #
+
+ # Absolute path to socket file that will be used for communication with the
+ # Pool Manager daemon (string value)
+ #sock_file = /run/kuryr/kuryr_manage.sock
+
+
+ [vif_pool]
+
+ #
+ # From kuryr_kubernetes
+ #
+
+ # Set a maximun amount of ports per pool. 0 to disable (integer value)
+ ports_pool_max = {{ kuryr_openstack_pool_max | default(0) }}
+
+ # Set a target minimum size of the pool of ports (integer value)
+ ports_pool_min = {{ kuryr_openstack_pool_min | default(1) }}
+
+ # Number of ports to be created in a bulk request (integer value)
+ ports_pool_batch = {{ kuryr_openstack_pool_batch | default(5) }}
+
+ # Minimun interval (in seconds) between pool updates (integer value)
+ ports_pool_update_frequency = {{ kuryr_openstack_pool_update_frequency | default(20) }}
diff --git a/roles/lib_utils/filter_plugins/oo_filters.py b/roles/lib_utils/filter_plugins/oo_filters.py
index fc14b5633..ef996fefe 100644
--- a/roles/lib_utils/filter_plugins/oo_filters.py
+++ b/roles/lib_utils/filter_plugins/oo_filters.py
@@ -4,6 +4,7 @@
"""
Custom filters for use in openshift-ansible
"""
+import json
import os
import pdb
import random
@@ -21,13 +22,10 @@ import yaml
from ansible import errors
from ansible.parsing.yaml.dumper import AnsibleDumper
-# ansible.compat.six goes away with Ansible 2.4
-try:
- from ansible.compat.six import string_types, u
- from ansible.compat.six.moves.urllib.parse import urlparse
-except ImportError:
- from ansible.module_utils.six import string_types, u
- from ansible.module_utils.six.moves.urllib.parse import urlparse
+# pylint: disable=import-error,no-name-in-module
+from ansible.module_utils.six import string_types, u
+# pylint: disable=import-error,no-name-in-module
+from ansible.module_utils.six.moves.urllib.parse import urlparse
HAS_OPENSSL = False
try:
@@ -589,6 +587,18 @@ that result to this filter plugin.
return secret_name
+def lib_utils_oo_l_of_d_to_csv(input_list):
+ """Map a list of dictionaries, input_list, into a csv string
+ of json values.
+
+ Example input:
+ [{'var1': 'val1', 'var2': 'val2'}, {'var1': 'val3', 'var2': 'val4'}]
+ Example output:
+ u'{"var1": "val1", "var2": "val2"},{"var1": "val3", "var2": "val4"}'
+ """
+ return ','.join(json.dumps(x) for x in input_list)
+
+
def map_from_pairs(source, delim="="):
''' Returns a dict given the source and delim delimited '''
if source == '':
@@ -626,5 +636,6 @@ class FilterModule(object):
"lib_utils_oo_contains_rule": lib_utils_oo_contains_rule,
"lib_utils_oo_selector_to_string_list": lib_utils_oo_selector_to_string_list,
"lib_utils_oo_filter_sa_secrets": lib_utils_oo_filter_sa_secrets,
+ "lib_utils_oo_l_of_d_to_csv": lib_utils_oo_l_of_d_to_csv,
"map_from_pairs": map_from_pairs
}
diff --git a/roles/lib_utils/filter_plugins/openshift_master.py b/roles/lib_utils/filter_plugins/openshift_master.py
index ff15f693b..e67b19c28 100644
--- a/roles/lib_utils/filter_plugins/openshift_master.py
+++ b/roles/lib_utils/filter_plugins/openshift_master.py
@@ -10,11 +10,7 @@ from ansible import errors
from ansible.parsing.yaml.dumper import AnsibleDumper
from ansible.plugins.filter.core import to_bool as ansible_bool
-# ansible.compat.six goes away with Ansible 2.4
-try:
- from ansible.compat.six import string_types, u
-except ImportError:
- from ansible.module_utils.six import string_types, u
+from ansible.module_utils.six import string_types, u
import yaml
diff --git a/roles/lib_utils/library/docker_creds.py b/roles/lib_utils/library/docker_creds.py
index d4674845e..b94c0b779 100644
--- a/roles/lib_utils/library/docker_creds.py
+++ b/roles/lib_utils/library/docker_creds.py
@@ -135,7 +135,7 @@ def update_config(docker_config, registry, username, password):
docker_config['auths'][registry] = {}
# base64 encode our username:password string
- encoded_data = base64.b64encode('{}:{}'.format(username, password))
+ encoded_data = base64.b64encode('{}:{}'.format(username, password).encode())
# check if the same value is already present for idempotency.
if 'auth' in docker_config['auths'][registry]:
@@ -151,7 +151,7 @@ def write_config(module, docker_config, dest):
conf_file_path = os.path.join(dest, 'config.json')
try:
with open(conf_file_path, 'w') as conf_file:
- json.dump(docker_config, conf_file, indent=8)
+ json.dump(docker_config.decode(), conf_file, indent=8)
except IOError as ioerror:
result = {'failed': True,
'changed': False,
diff --git a/roles/openshift_aws/defaults/main.yml b/roles/openshift_aws/defaults/main.yml
index 6de603661..e14d57702 100644
--- a/roles/openshift_aws/defaults/main.yml
+++ b/roles/openshift_aws/defaults/main.yml
@@ -59,7 +59,7 @@ openshift_aws_elb_name_dict:
external: "{{ openshift_aws_elb_basename }}-infra"
openshift_aws_elb_idle_timout: 400
-openshift_aws_elb_scheme: internet-facing
+
openshift_aws_elb_cert_arn: ''
openshift_aws_elb_dict:
@@ -98,12 +98,20 @@ openshift_aws_elb_dict:
proxy_protocol: True
openshift_aws_node_group_config_master_volumes:
+- device_name: /dev/sda1
+ volume_size: 100
+ device_type: gp2
+ delete_on_termination: False
- device_name: /dev/sdb
volume_size: 100
device_type: gp2
delete_on_termination: False
openshift_aws_node_group_config_node_volumes:
+- device_name: /dev/sda1
+ volume_size: 100
+ device_type: gp2
+ delete_on_termination: True
- device_name: /dev/sdb
volume_size: 100
device_type: gp2
@@ -294,3 +302,7 @@ openshift_aws_node_user_data: ''
openshift_aws_node_config_namespace: openshift-node
openshift_aws_masters_groups: masters,etcd,nodes
+
+# By default, don't delete things like the shared IAM instance
+# profile and uploaded ssh keys
+openshift_aws_enable_uninstall_shared_objects: False
diff --git a/roles/openshift_aws/tasks/accept_nodes.yml b/roles/openshift_aws/tasks/accept_nodes.yml
index c2a2cea30..db30fe5c9 100644
--- a/roles/openshift_aws/tasks/accept_nodes.yml
+++ b/roles/openshift_aws/tasks/accept_nodes.yml
@@ -1,4 +1,6 @@
---
+- include_tasks: setup_master_group.yml
+
- name: fetch masters
ec2_instance_facts:
region: "{{ openshift_aws_region | default('us-east-1') }}"
@@ -36,4 +38,4 @@
nodes: "{{ instancesout.instances|map(attribute='private_dns_name') | list }}"
timeout: 60
register: nodeout
- delegate_to: "{{ mastersout.instances[0].public_ip_address }}"
+ delegate_to: "{{ groups.masters.0 }}"
diff --git a/roles/openshift_aws/tasks/elb.yml b/roles/openshift_aws/tasks/elb.yml
index 5d371ec7a..6f0028a3d 100644
--- a/roles/openshift_aws/tasks/elb.yml
+++ b/roles/openshift_aws/tasks/elb.yml
@@ -15,7 +15,7 @@
- "{{ subnetout.subnets[0].id }}"
health_check: "{{ openshift_aws_elb_health_check }}"
listeners: "{{ item.value }}"
- scheme: "{{ openshift_aws_elb_scheme }}"
+ scheme: "{{ (item.key == 'internal') | ternary('internal','internet-facing') }}"
tags: "{{ openshift_aws_elb_tags }}"
wait: True
register: new_elb
diff --git a/roles/openshift_aws/tasks/provision.yml b/roles/openshift_aws/tasks/provision.yml
index 786a2e4cf..2b5f317d8 100644
--- a/roles/openshift_aws/tasks/provision.yml
+++ b/roles/openshift_aws/tasks/provision.yml
@@ -1,23 +1,6 @@
---
-- when: openshift_aws_create_iam_cert | bool
- name: create the iam_cert for elb certificate
- include_tasks: iam_cert.yml
-
-- when: openshift_aws_create_s3 | bool
- name: create s3 bucket for registry
- include_tasks: s3.yml
-
- include_tasks: vpc_and_subnet_id.yml
-- name: create elbs
- include_tasks: elb.yml
- with_dict: "{{ openshift_aws_elb_dict }}"
- vars:
- l_elb_security_groups: "{{ openshift_aws_elb_security_groups }}"
- l_openshift_aws_elb_name_dict: "{{ openshift_aws_elb_name_dict }}"
- loop_control:
- loop_var: l_elb_dict_item
-
- name: include scale group creation for master
include_tasks: build_node_group.yml
with_items: "{{ openshift_aws_master_group }}"
diff --git a/roles/openshift_aws/tasks/provision_elb.yml b/roles/openshift_aws/tasks/provision_elb.yml
new file mode 100644
index 000000000..a52f63bd5
--- /dev/null
+++ b/roles/openshift_aws/tasks/provision_elb.yml
@@ -0,0 +1,15 @@
+---
+- when: openshift_aws_create_iam_cert | bool
+ name: create the iam_cert for elb certificate
+ include_tasks: iam_cert.yml
+
+- include_tasks: vpc_and_subnet_id.yml
+
+- name: create elbs
+ include_tasks: elb.yml
+ with_dict: "{{ openshift_aws_elb_dict }}"
+ vars:
+ l_elb_security_groups: "{{ openshift_aws_elb_security_groups }}"
+ l_openshift_aws_elb_name_dict: "{{ openshift_aws_elb_name_dict }}"
+ loop_control:
+ loop_var: l_elb_dict_item
diff --git a/roles/openshift_aws/tasks/provision_nodes.yml b/roles/openshift_aws/tasks/provision_nodes.yml
index d82f18574..9105b5b4c 100644
--- a/roles/openshift_aws/tasks/provision_nodes.yml
+++ b/roles/openshift_aws/tasks/provision_nodes.yml
@@ -2,25 +2,12 @@
# Get bootstrap config token
# bootstrap should be created on first master
# need to fetch it and shove it into cloud data
-- name: fetch master instances
- ec2_instance_facts:
- region: "{{ openshift_aws_region }}"
- filters:
- "tag:clusterid": "{{ openshift_aws_clusterid }}"
- "tag:host-type": master
- instance-state-name: running
- register: instancesout
- retries: 20
- delay: 3
- until:
- - "'instances' in instancesout"
- - instancesout.instances|length > 0
+- include_tasks: setup_master_group.yml
- name: slurp down the bootstrap.kubeconfig
slurp:
src: /etc/origin/master/bootstrap.kubeconfig
- delegate_to: "{{ instancesout.instances[0].public_ip_address }}"
- remote_user: root
+ delegate_to: "{{ groups.masters.0 }}"
register: bootstrap
- name: set_fact for kubeconfig token
diff --git a/roles/openshift_aws/tasks/uninstall_security_group.yml b/roles/openshift_aws/tasks/uninstall_security_group.yml
new file mode 100644
index 000000000..55d40e8ec
--- /dev/null
+++ b/roles/openshift_aws/tasks/uninstall_security_group.yml
@@ -0,0 +1,14 @@
+---
+- name: delete the node group sgs
+ oo_ec2_group:
+ state: absent
+ name: "{{ item.value.name}}"
+ region: "{{ openshift_aws_region }}"
+ with_dict: "{{ openshift_aws_node_security_groups }}"
+
+- name: delete the k8s sgs for the node group
+ oo_ec2_group:
+ state: absent
+ name: "{{ item.value.name }}_k8s"
+ region: "{{ openshift_aws_region }}"
+ with_dict: "{{ openshift_aws_node_security_groups }}"
diff --git a/roles/openshift_aws/tasks/uninstall_ssh_keys.yml b/roles/openshift_aws/tasks/uninstall_ssh_keys.yml
new file mode 100644
index 000000000..27e42da53
--- /dev/null
+++ b/roles/openshift_aws/tasks/uninstall_ssh_keys.yml
@@ -0,0 +1,9 @@
+---
+- name: Remove the public keys for the user(s)
+ ec2_key:
+ state: absent
+ name: "{{ item.key_name }}"
+ region: "{{ openshift_aws_region }}"
+ with_items: "{{ openshift_aws_users }}"
+ no_log: True
+ when: openshift_aws_enable_uninstall_shared_objects | bool
diff --git a/roles/openshift_aws/tasks/uninstall_vpc.yml b/roles/openshift_aws/tasks/uninstall_vpc.yml
new file mode 100644
index 000000000..ecf39f694
--- /dev/null
+++ b/roles/openshift_aws/tasks/uninstall_vpc.yml
@@ -0,0 +1,36 @@
+---
+- name: Fetch the VPC for the vpc.id
+ ec2_vpc_net_facts:
+ region: "{{ openshift_aws_region }}"
+ filters:
+ "tag:Name": "{{ openshift_aws_clusterid }}"
+ register: vpcout
+- debug:
+ var: vpcout
+ verbosity: 1
+
+- when: vpcout.vpcs | length > 0
+ block:
+ - name: delete the vpc igw
+ ec2_vpc_igw:
+ state: absent
+ region: "{{ openshift_aws_region }}"
+ vpc_id: "{{ vpcout.vpcs[0].id }}"
+ register: igw
+
+ - name: delete the vpc subnets
+ ec2_vpc_subnet:
+ state: absent
+ region: "{{ openshift_aws_region }}"
+ vpc_id: "{{ vpcout.vpcs[0].id }}"
+ cidr: "{{ item.cidr }}"
+ az: "{{ item.az }}"
+ with_items: "{{ openshift_aws_vpc.subnets[openshift_aws_region] }}"
+
+ - name: Delete AWS VPC
+ ec2_vpc_net:
+ state: absent
+ region: "{{ openshift_aws_region }}"
+ name: "{{ openshift_aws_clusterid }}"
+ cidr_block: "{{ openshift_aws_vpc.cidr }}"
+ register: vpc
diff --git a/roles/openshift_bootstrap_autoapprover/files/openshift-bootstrap-controller-policy.yaml b/roles/openshift_bootstrap_autoapprover/files/openshift-bootstrap-controller-policy.yaml
new file mode 100644
index 000000000..90ee40943
--- /dev/null
+++ b/roles/openshift_bootstrap_autoapprover/files/openshift-bootstrap-controller-policy.yaml
@@ -0,0 +1,10 @@
+kind: ClusterRoleBinding
+apiVersion: rbac.authorization.k8s.io/v1beta1
+metadata:
+ name: bootstrap-autoapprover
+roleRef:
+ kind: ClusterRole
+ name: system:node-bootstrap-autoapprover
+subjects:
+- kind: User
+ name: system:serviceaccount:openshift-infra:bootstrap-autoapprover
diff --git a/roles/openshift_bootstrap_autoapprover/files/openshift-bootstrap-controller-role.yaml b/roles/openshift_bootstrap_autoapprover/files/openshift-bootstrap-controller-role.yaml
new file mode 100644
index 000000000..d8143d047
--- /dev/null
+++ b/roles/openshift_bootstrap_autoapprover/files/openshift-bootstrap-controller-role.yaml
@@ -0,0 +1,21 @@
+apiVersion: rbac.authorization.k8s.io/v1beta1
+kind: ClusterRole
+metadata:
+ name: system:node-bootstrap-autoapprover
+rules:
+- apiGroups:
+ - certificates.k8s.io
+ resources:
+ - certificatesigningrequests
+ verbs:
+ - delete
+ - get
+ - list
+ - watch
+- apiGroups:
+ - certificates.k8s.io
+ resources:
+ - certificatesigningrequests/approval
+ verbs:
+ - create
+ - update
diff --git a/roles/openshift_bootstrap_autoapprover/files/openshift-bootstrap-controller-serviceaccount.yaml b/roles/openshift_bootstrap_autoapprover/files/openshift-bootstrap-controller-serviceaccount.yaml
new file mode 100644
index 000000000..e22ce6f34
--- /dev/null
+++ b/roles/openshift_bootstrap_autoapprover/files/openshift-bootstrap-controller-serviceaccount.yaml
@@ -0,0 +1,5 @@
+kind: ServiceAccount
+apiVersion: v1
+metadata:
+ name: bootstrap-autoapprover
+ namespace: openshift-infra
diff --git a/roles/openshift_bootstrap_autoapprover/files/openshift-bootstrap-controller.yaml b/roles/openshift_bootstrap_autoapprover/files/openshift-bootstrap-controller.yaml
new file mode 100644
index 000000000..dbcedb407
--- /dev/null
+++ b/roles/openshift_bootstrap_autoapprover/files/openshift-bootstrap-controller.yaml
@@ -0,0 +1,68 @@
+kind: StatefulSet
+apiVersion: apps/v1beta1
+metadata:
+ name: bootstrap-autoapprover
+ namespace: openshift-infra
+spec:
+ updateStrategy:
+ type: RollingUpdate
+ template:
+ metadata:
+ labels:
+ app: bootstrap-autoapprover
+ spec:
+ serviceAccountName: bootstrap-autoapprover
+ terminationGracePeriodSeconds: 1
+ containers:
+ - name: signer
+ image: openshift/node:v3.7.0-rc.0
+ command:
+ - /bin/bash
+ - -c
+ args:
+ - |
+ #!/bin/bash
+ set -o errexit
+ set -o nounset
+ set -o pipefail
+
+ unset KUBECONFIG
+ cat <<SCRIPT > /tmp/signer
+ #!/bin/bash
+ #
+ # It will approve any CSR that is not approved yet, and delete any CSR that expired more than 60 seconds
+ # ago.
+ #
+
+ set -o errexit
+ set -o nounset
+ set -o pipefail
+
+ name=\${1}
+ condition=\${2}
+ certificate=\${3}
+ username=\${4}
+
+ # auto approve
+ if [[ -z "\${condition}" && ("\${username}" == "system:serviceaccount:openshift-infra:node-bootstrapper" || "\${username}" == "system:node:"* ) ]]; then
+ oc adm certificate approve "\${name}"
+ exit 0
+ fi
+
+ # check certificate age
+ if [[ -n "\${certificate}" ]]; then
+ text="\$( echo "\${certificate}" | base64 -d - )"
+ if ! echo "\${text}" | openssl x509 -noout; then
+ echo "error: Unable to parse certificate" 2>&1
+ exit 1
+ fi
+ if ! echo "\${text}" | openssl x509 -checkend -60 > /dev/null; then
+ echo "Certificate is expired, deleting"
+ oc delete csr "\${name}"
+ fi
+ exit 0
+ fi
+ SCRIPT
+ chmod u+x /tmp/signer
+
+ exec oc observe csr --maximum-errors=1 --resync-period=10m -a '{.status.conditions[*].type}' -a '{.status.certificate}' -a '{.spec.username}' -- /tmp/signer
diff --git a/roles/openshift_bootstrap_autoapprover/tasks/main.yml b/roles/openshift_bootstrap_autoapprover/tasks/main.yml
new file mode 100644
index 000000000..88e9d08e7
--- /dev/null
+++ b/roles/openshift_bootstrap_autoapprover/tasks/main.yml
@@ -0,0 +1,28 @@
+---
+- name: Copy auto-approver config to host
+ run_once: true
+ copy:
+ src: "{{ item }}"
+ dest: /tmp/openshift-approver/
+ owner: root
+ mode: 0400
+ with_fileglob:
+ - "*.yaml"
+
+- name: Set auto-approver nodeSelector
+ run_once: true
+ yedit:
+ src: "/tmp/openshift-approver/openshift-bootstrap-controller.yaml"
+ key: spec.template.spec.nodeSelector
+ value: "{{ openshift_master_bootstrap_auto_approver_node_selector | default({}) }}"
+ value_type: list
+
+- name: Create auto-approver on cluster
+ run_once: true
+ command: oc apply -f /tmp/openshift-approver/
+
+- name: Remove auto-approver config
+ run_once: true
+ file:
+ path: /tmp/openshift-approver/
+ state: absent
diff --git a/roles/openshift_ca/tasks/main.yml b/roles/openshift_ca/tasks/main.yml
index b94cd9fba..9c8534c74 100644
--- a/roles/openshift_ca/tasks/main.yml
+++ b/roles/openshift_ca/tasks/main.yml
@@ -19,7 +19,8 @@
- name: Reload generated facts
openshift_facts:
- when: hostvars[openshift_ca_host].install_result is changed
+ when:
+ - hostvars[openshift_ca_host].install_result | default({'changed':false}) is changed
- name: Create openshift_ca_config_dir if it does not exist
file:
diff --git a/roles/openshift_cloud_provider/tasks/gce.yml b/roles/openshift_cloud_provider/tasks/gce.yml
index ee4048911..395bd304c 100644
--- a/roles/openshift_cloud_provider/tasks/gce.yml
+++ b/roles/openshift_cloud_provider/tasks/gce.yml
@@ -13,5 +13,11 @@
ini_file:
dest: "{{ openshift.common.config_base }}/cloudprovider/gce.conf"
section: Global
- option: multizone
- value: "true"
+ option: "{{ item.key }}"
+ value: "{{ item.value }}"
+ with_items:
+ - { key: 'project-id', value: '{{ openshift_gcp_project }}' }
+ - { key: 'network-name', value: '{{ openshift_gcp_network_name }}' }
+ - { key: 'node-tags', value: '{{ openshift_gcp_prefix }}ocp' }
+ - { key: 'node-instance-prefix', value: '{{ openshift_gcp_prefix }}' }
+ - { key: 'multizone', value: 'false' }
diff --git a/roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-backup-job.yaml b/roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-backup-job.yaml
new file mode 100644
index 000000000..48d1d4e26
--- /dev/null
+++ b/roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-backup-job.yaml
@@ -0,0 +1,28 @@
+apiVersion: batch/v1
+kind: Job
+metadata:
+ name: cloudforms-backup
+spec:
+ template:
+ metadata:
+ name: cloudforms-backup
+ spec:
+ containers:
+ - name: postgresql
+ image: registry.access.redhat.com/cloudforms46-beta/cfme-openshift-postgresql:latest
+ command:
+ - "/opt/rh/cfme-container-scripts/backup_db"
+ env:
+ - name: DATABASE_URL
+ valueFrom:
+ secretKeyRef:
+ name: cloudforms-secrets
+ key: database-url
+ volumeMounts:
+ - name: cfme-backup-vol
+ mountPath: "/backups"
+ volumes:
+ - name: cfme-backup-vol
+ persistentVolumeClaim:
+ claimName: cloudforms-backup
+ restartPolicy: Never
diff --git a/roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-backup-pvc.yaml b/roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-backup-pvc.yaml
new file mode 100644
index 000000000..92598ce82
--- /dev/null
+++ b/roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-backup-pvc.yaml
@@ -0,0 +1,10 @@
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+ name: cloudforms-backup
+spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 15Gi
diff --git a/roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-pv-backup-example.yaml b/roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-pv-backup-example.yaml
new file mode 100644
index 000000000..4fe349897
--- /dev/null
+++ b/roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-pv-backup-example.yaml
@@ -0,0 +1,13 @@
+apiVersion: v1
+kind: PersistentVolume
+metadata:
+ name: cfme-pv03
+spec:
+ capacity:
+ storage: 15Gi
+ accessModes:
+ - ReadWriteOnce
+ nfs:
+ path: "/exports/cfme-pv03"
+ server: "<your-nfs-host-here>"
+ persistentVolumeReclaimPolicy: Retain
diff --git a/roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-pv-db-example.yaml b/roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-pv-db-example.yaml
index 250a99b8d..0cdd821b5 100644
--- a/roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-pv-db-example.yaml
+++ b/roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-pv-db-example.yaml
@@ -1,13 +1,38 @@
apiVersion: v1
-kind: PersistentVolume
+kind: Template
+labels:
+ template: cloudforms-db-pv
metadata:
- name: cfme-pv01
-spec:
- capacity:
- storage: 15Gi
- accessModes:
+ name: cloudforms-db-pv
+ annotations:
+ description: PV Template for CFME PostgreSQL DB
+ tags: PVS, CFME
+objects:
+- apiVersion: v1
+ kind: PersistentVolume
+ metadata:
+ name: cfme-db
+ spec:
+ capacity:
+ storage: "${PV_SIZE}"
+ accessModes:
- ReadWriteOnce
- nfs:
- path: /exports/cfme-pv01
- server: <your-nfs-host-here>
- persistentVolumeReclaimPolicy: Retain
+ nfs:
+ path: "${BASE_PATH}/cfme-db"
+ server: "${NFS_HOST}"
+ persistentVolumeReclaimPolicy: Retain
+parameters:
+- name: PV_SIZE
+ displayName: PV Size for DB
+ required: true
+ description: The size of the CFME DB PV given in Gi
+ value: 15Gi
+- name: BASE_PATH
+ displayName: Exports Directory Base Path
+ required: true
+ description: The parent directory of your NFS exports
+ value: "/exports"
+- name: NFS_HOST
+ displayName: NFS Server Hostname
+ required: true
+ description: The hostname or IP address of the NFS server
diff --git a/roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-pv-region-example.yaml b/roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-pv-region-example.yaml
deleted file mode 100644
index cba9bbe35..000000000
--- a/roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-pv-region-example.yaml
+++ /dev/null
@@ -1,13 +0,0 @@
-apiVersion: v1
-kind: PersistentVolume
-metadata:
- name: cfme-pv02
-spec:
- capacity:
- storage: 5Gi
- accessModes:
- - ReadWriteOnce
- nfs:
- path: /exports/cfme-pv02
- server: <your-nfs-host-here>
- persistentVolumeReclaimPolicy: Retain
diff --git a/roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-pv-server-example.yaml b/roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-pv-server-example.yaml
index c08c21265..527090ae8 100644
--- a/roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-pv-server-example.yaml
+++ b/roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-pv-server-example.yaml
@@ -1,13 +1,38 @@
apiVersion: v1
-kind: PersistentVolume
+kind: Template
+labels:
+ template: cloudforms-app-pv
metadata:
- name: cfme-pv03
-spec:
- capacity:
- storage: 5Gi
- accessModes:
+ name: cloudforms-app-pv
+ annotations:
+ description: PV Template for CFME Server
+ tags: PVS, CFME
+objects:
+- apiVersion: v1
+ kind: PersistentVolume
+ metadata:
+ name: cfme-app
+ spec:
+ capacity:
+ storage: "${PV_SIZE}"
+ accessModes:
- ReadWriteOnce
- nfs:
- path: /exports/cfme-pv03
- server: <your-nfs-host-here>
- persistentVolumeReclaimPolicy: Retain
+ nfs:
+ path: "${BASE_PATH}/cfme-app"
+ server: "${NFS_HOST}"
+ persistentVolumeReclaimPolicy: Retain
+parameters:
+- name: PV_SIZE
+ displayName: PV Size for App
+ required: true
+ description: The size of the CFME APP PV given in Gi
+ value: 5Gi
+- name: BASE_PATH
+ displayName: Exports Directory Base Path
+ required: true
+ description: The parent directory of your NFS exports
+ value: "/exports"
+- name: NFS_HOST
+ displayName: NFS Server Hostname
+ required: true
+ description: The hostname or IP address of the NFS server
diff --git a/roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-restore-job.yaml b/roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-restore-job.yaml
new file mode 100644
index 000000000..7fd4fc2e1
--- /dev/null
+++ b/roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-restore-job.yaml
@@ -0,0 +1,35 @@
+apiVersion: batch/v1
+kind: Job
+metadata:
+ name: cloudforms-restore
+spec:
+ template:
+ metadata:
+ name: cloudforms-restore
+ spec:
+ containers:
+ - name: postgresql
+ image: registry.access.redhat.com/cloudforms46-beta/cfme-openshift-postgresql:latest
+ command:
+ - "/opt/rh/cfme-container-scripts/restore_db"
+ env:
+ - name: DATABASE_URL
+ valueFrom:
+ secretKeyRef:
+ name: cloudforms-secrets
+ key: database-url
+ - name: BACKUP_VERSION
+ value: latest
+ volumeMounts:
+ - name: cfme-backup-vol
+ mountPath: "/backups"
+ - name: cfme-prod-vol
+ mountPath: "/restore"
+ volumes:
+ - name: cfme-backup-vol
+ persistentVolumeClaim:
+ claimName: cloudforms-backup
+ - name: cfme-prod-vol
+ persistentVolumeClaim:
+ claimName: cloudforms-postgresql
+ restartPolicy: Never
diff --git a/roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-scc-sysadmin.yaml b/roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-scc-sysadmin.yaml
new file mode 100644
index 000000000..d2ece9298
--- /dev/null
+++ b/roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-scc-sysadmin.yaml
@@ -0,0 +1,38 @@
+allowHostDirVolumePlugin: false
+allowHostIPC: false
+allowHostNetwork: false
+allowHostPID: false
+allowHostPorts: false
+allowPrivilegedContainer: false
+allowedCapabilities:
+apiVersion: v1
+defaultAddCapabilities:
+- SYS_ADMIN
+fsGroup:
+ type: RunAsAny
+groups:
+- system:cluster-admins
+kind: SecurityContextConstraints
+metadata:
+ annotations:
+ kubernetes.io/description: cfme-sysadmin provides all features of the anyuid SCC but allows users to have SYS_ADMIN capabilities. This is the required scc for Pods requiring to run with systemd and the message bus.
+ creationTimestamp:
+ name: cfme-sysadmin
+priority: 10
+readOnlyRootFilesystem: false
+requiredDropCapabilities:
+- MKNOD
+- SYS_CHROOT
+runAsUser:
+ type: RunAsAny
+seLinuxContext:
+ type: MustRunAs
+supplementalGroups:
+ type: RunAsAny
+users:
+volumes:
+- configMap
+- downwardAPI
+- emptyDir
+- persistentVolumeClaim
+- secret
diff --git a/roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-template-ext-db.yaml b/roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-template-ext-db.yaml
new file mode 100644
index 000000000..9866c29c3
--- /dev/null
+++ b/roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-template-ext-db.yaml
@@ -0,0 +1,956 @@
+apiVersion: v1
+kind: Template
+labels:
+ template: cloudforms-ext-db
+metadata:
+ name: cloudforms-ext-db
+ annotations:
+ description: CloudForms appliance with persistent storage using a external DB host
+ tags: instant-app,cloudforms,cfme
+ iconClass: icon-rails
+objects:
+- apiVersion: v1
+ kind: ServiceAccount
+ metadata:
+ name: cfme-orchestrator
+- apiVersion: v1
+ kind: ServiceAccount
+ metadata:
+ name: cfme-anyuid
+- apiVersion: v1
+ kind: ServiceAccount
+ metadata:
+ name: cfme-privileged
+- apiVersion: v1
+ kind: ServiceAccount
+ metadata:
+ name: cfme-httpd
+- apiVersion: v1
+ kind: Secret
+ metadata:
+ name: "${NAME}-secrets"
+ stringData:
+ pg-password: "${DATABASE_PASSWORD}"
+ admin-password: "${APPLICATION_ADMIN_PASSWORD}"
+ database-url: postgresql://${DATABASE_USER}:${DATABASE_PASSWORD}@${DATABASE_SERVICE_NAME}/${DATABASE_NAME}?encoding=utf8&pool=5&wait_timeout=5
+ v2-key: "${V2_KEY}"
+- apiVersion: v1
+ kind: Secret
+ metadata:
+ name: "${ANSIBLE_SERVICE_NAME}-secrets"
+ stringData:
+ rabbit-password: "${ANSIBLE_RABBITMQ_PASSWORD}"
+ secret-key: "${ANSIBLE_SECRET_KEY}"
+ admin-password: "${ANSIBLE_ADMIN_PASSWORD}"
+- apiVersion: v1
+ kind: Service
+ metadata:
+ annotations:
+ description: Exposes and load balances CloudForms pods
+ service.alpha.openshift.io/dependencies: '[{"name":"${DATABASE_SERVICE_NAME}","namespace":"","kind":"Service"},{"name":"${MEMCACHED_SERVICE_NAME}","namespace":"","kind":"Service"}]'
+ name: "${NAME}"
+ spec:
+ clusterIP: None
+ ports:
+ - name: http
+ port: 80
+ protocol: TCP
+ targetPort: 80
+ selector:
+ name: "${NAME}"
+- apiVersion: v1
+ kind: Route
+ metadata:
+ name: "${HTTPD_SERVICE_NAME}"
+ spec:
+ host: "${APPLICATION_DOMAIN}"
+ port:
+ targetPort: http
+ tls:
+ termination: edge
+ insecureEdgeTerminationPolicy: Redirect
+ to:
+ kind: Service
+ name: "${HTTPD_SERVICE_NAME}"
+- apiVersion: apps/v1beta1
+ kind: StatefulSet
+ metadata:
+ name: "${NAME}"
+ annotations:
+ description: Defines how to deploy the CloudForms appliance
+ spec:
+ serviceName: "${NAME}"
+ replicas: "${APPLICATION_REPLICA_COUNT}"
+ template:
+ metadata:
+ labels:
+ name: "${NAME}"
+ name: "${NAME}"
+ spec:
+ containers:
+ - name: cloudforms
+ image: "${FRONTEND_APPLICATION_IMG_NAME}:${FRONTEND_APPLICATION_IMG_TAG}"
+ livenessProbe:
+ exec:
+ command:
+ - pidof
+ - MIQ Server
+ initialDelaySeconds: 480
+ timeoutSeconds: 3
+ readinessProbe:
+ tcpSocket:
+ port: 80
+ initialDelaySeconds: 200
+ timeoutSeconds: 3
+ ports:
+ - containerPort: 80
+ protocol: TCP
+ volumeMounts:
+ - name: "${NAME}-server"
+ mountPath: "/persistent"
+ env:
+ - name: MY_POD_NAMESPACE
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.namespace
+ - name: APPLICATION_INIT_DELAY
+ value: "${APPLICATION_INIT_DELAY}"
+ - name: DATABASE_REGION
+ value: "${DATABASE_REGION}"
+ - name: DATABASE_URL
+ valueFrom:
+ secretKeyRef:
+ name: "${NAME}-secrets"
+ key: database-url
+ - name: V2_KEY
+ valueFrom:
+ secretKeyRef:
+ name: "${NAME}-secrets"
+ key: v2-key
+ - name: APPLICATION_ADMIN_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: "${NAME}-secrets"
+ key: admin-password
+ - name: ANSIBLE_ADMIN_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: "${ANSIBLE_SERVICE_NAME}-secrets"
+ key: admin-password
+ resources:
+ requests:
+ memory: "${APPLICATION_MEM_REQ}"
+ cpu: "${APPLICATION_CPU_REQ}"
+ limits:
+ memory: "${APPLICATION_MEM_LIMIT}"
+ lifecycle:
+ preStop:
+ exec:
+ command:
+ - "/opt/rh/cfme-container-scripts/sync-pv-data"
+ serviceAccount: cfme-orchestrator
+ serviceAccountName: cfme-orchestrator
+ terminationGracePeriodSeconds: 90
+ volumeClaimTemplates:
+ - metadata:
+ name: "${NAME}-server"
+ annotations:
+ spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: "${APPLICATION_VOLUME_CAPACITY}"
+- apiVersion: v1
+ kind: Service
+ metadata:
+ annotations:
+ description: Headless service for CloudForms backend pods
+ name: "${NAME}-backend"
+ spec:
+ clusterIP: None
+ selector:
+ name: "${NAME}-backend"
+- apiVersion: apps/v1beta1
+ kind: StatefulSet
+ metadata:
+ name: "${NAME}-backend"
+ annotations:
+ description: Defines how to deploy the CloudForms appliance
+ spec:
+ serviceName: "${NAME}-backend"
+ replicas: 0
+ template:
+ metadata:
+ labels:
+ name: "${NAME}-backend"
+ name: "${NAME}-backend"
+ spec:
+ containers:
+ - name: cloudforms
+ image: "${BACKEND_APPLICATION_IMG_NAME}:${BACKEND_APPLICATION_IMG_TAG}"
+ livenessProbe:
+ exec:
+ command:
+ - pidof
+ - MIQ Server
+ initialDelaySeconds: 480
+ timeoutSeconds: 3
+ volumeMounts:
+ - name: "${NAME}-server"
+ mountPath: "/persistent"
+ env:
+ - name: APPLICATION_INIT_DELAY
+ value: "${APPLICATION_INIT_DELAY}"
+ - name: DATABASE_URL
+ valueFrom:
+ secretKeyRef:
+ name: "${NAME}-secrets"
+ key: database-url
+ - name: MIQ_SERVER_DEFAULT_ROLES
+ value: database_operations,event,reporting,scheduler,smartstate,ems_operations,ems_inventory,automate
+ - name: FRONTEND_SERVICE_NAME
+ value: "${NAME}"
+ - name: V2_KEY
+ valueFrom:
+ secretKeyRef:
+ name: "${NAME}-secrets"
+ key: v2-key
+ - name: ANSIBLE_ADMIN_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: "${ANSIBLE_SERVICE_NAME}-secrets"
+ key: admin-password
+ resources:
+ requests:
+ memory: "${APPLICATION_MEM_REQ}"
+ cpu: "${APPLICATION_CPU_REQ}"
+ limits:
+ memory: "${APPLICATION_MEM_LIMIT}"
+ lifecycle:
+ preStop:
+ exec:
+ command:
+ - "/opt/rh/cfme-container-scripts/sync-pv-data"
+ serviceAccount: cfme-orchestrator
+ serviceAccountName: cfme-orchestrator
+ terminationGracePeriodSeconds: 90
+ volumeClaimTemplates:
+ - metadata:
+ name: "${NAME}-server"
+ annotations:
+ spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: "${APPLICATION_VOLUME_CAPACITY}"
+- apiVersion: v1
+ kind: Service
+ metadata:
+ name: "${MEMCACHED_SERVICE_NAME}"
+ annotations:
+ description: Exposes the memcached server
+ spec:
+ ports:
+ - name: memcached
+ port: 11211
+ targetPort: 11211
+ selector:
+ name: "${MEMCACHED_SERVICE_NAME}"
+- apiVersion: v1
+ kind: DeploymentConfig
+ metadata:
+ name: "${MEMCACHED_SERVICE_NAME}"
+ annotations:
+ description: Defines how to deploy memcached
+ spec:
+ strategy:
+ type: Recreate
+ triggers:
+ - type: ConfigChange
+ replicas: 1
+ selector:
+ name: "${MEMCACHED_SERVICE_NAME}"
+ template:
+ metadata:
+ name: "${MEMCACHED_SERVICE_NAME}"
+ labels:
+ name: "${MEMCACHED_SERVICE_NAME}"
+ spec:
+ volumes: []
+ containers:
+ - name: memcached
+ image: "${MEMCACHED_IMG_NAME}:${MEMCACHED_IMG_TAG}"
+ ports:
+ - containerPort: 11211
+ readinessProbe:
+ timeoutSeconds: 1
+ initialDelaySeconds: 5
+ tcpSocket:
+ port: 11211
+ livenessProbe:
+ timeoutSeconds: 1
+ initialDelaySeconds: 30
+ tcpSocket:
+ port: 11211
+ volumeMounts: []
+ env:
+ - name: MEMCACHED_MAX_MEMORY
+ value: "${MEMCACHED_MAX_MEMORY}"
+ - name: MEMCACHED_MAX_CONNECTIONS
+ value: "${MEMCACHED_MAX_CONNECTIONS}"
+ - name: MEMCACHED_SLAB_PAGE_SIZE
+ value: "${MEMCACHED_SLAB_PAGE_SIZE}"
+ resources:
+ requests:
+ memory: "${MEMCACHED_MEM_REQ}"
+ cpu: "${MEMCACHED_CPU_REQ}"
+ limits:
+ memory: "${MEMCACHED_MEM_LIMIT}"
+- apiVersion: v1
+ kind: Service
+ metadata:
+ name: "${DATABASE_SERVICE_NAME}"
+ annotations:
+ description: Remote database service
+ spec:
+ ports:
+ - name: postgresql
+ port: 5432
+ targetPort: "${{DATABASE_PORT}}"
+ selector: {}
+- apiVersion: v1
+ kind: Endpoints
+ metadata:
+ name: "${DATABASE_SERVICE_NAME}"
+ subsets:
+ - addresses:
+ - ip: "${DATABASE_IP}"
+ ports:
+ - port: "${{DATABASE_PORT}}"
+ name: postgresql
+- apiVersion: v1
+ kind: Service
+ metadata:
+ annotations:
+ description: Exposes and load balances Ansible pods
+ service.alpha.openshift.io/dependencies: '[{"name":"${DATABASE_SERVICE_NAME}","namespace":"","kind":"Service"}]'
+ name: "${ANSIBLE_SERVICE_NAME}"
+ spec:
+ ports:
+ - name: http
+ port: 80
+ protocol: TCP
+ targetPort: 80
+ - name: https
+ port: 443
+ protocol: TCP
+ targetPort: 443
+ selector:
+ name: "${ANSIBLE_SERVICE_NAME}"
+- apiVersion: v1
+ kind: DeploymentConfig
+ metadata:
+ name: "${ANSIBLE_SERVICE_NAME}"
+ annotations:
+ description: Defines how to deploy the Ansible appliance
+ spec:
+ strategy:
+ type: Recreate
+ serviceName: "${ANSIBLE_SERVICE_NAME}"
+ replicas: 0
+ template:
+ metadata:
+ labels:
+ name: "${ANSIBLE_SERVICE_NAME}"
+ name: "${ANSIBLE_SERVICE_NAME}"
+ spec:
+ containers:
+ - name: ansible
+ image: "${ANSIBLE_IMG_NAME}:${ANSIBLE_IMG_TAG}"
+ livenessProbe:
+ tcpSocket:
+ port: 443
+ initialDelaySeconds: 480
+ timeoutSeconds: 3
+ readinessProbe:
+ httpGet:
+ path: "/"
+ port: 443
+ scheme: HTTPS
+ initialDelaySeconds: 200
+ timeoutSeconds: 3
+ ports:
+ - containerPort: 80
+ protocol: TCP
+ - containerPort: 443
+ protocol: TCP
+ securityContext:
+ privileged: true
+ env:
+ - name: ADMIN_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: "${ANSIBLE_SERVICE_NAME}-secrets"
+ key: admin-password
+ - name: RABBITMQ_USER_NAME
+ value: "${ANSIBLE_RABBITMQ_USER_NAME}"
+ - name: RABBITMQ_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: "${ANSIBLE_SERVICE_NAME}-secrets"
+ key: rabbit-password
+ - name: ANSIBLE_SECRET_KEY
+ valueFrom:
+ secretKeyRef:
+ name: "${ANSIBLE_SERVICE_NAME}-secrets"
+ key: secret-key
+ - name: DATABASE_SERVICE_NAME
+ value: "${DATABASE_SERVICE_NAME}"
+ - name: POSTGRESQL_USER
+ value: "${DATABASE_USER}"
+ - name: POSTGRESQL_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: "${NAME}-secrets"
+ key: pg-password
+ - name: POSTGRESQL_DATABASE
+ value: "${ANSIBLE_DATABASE_NAME}"
+ resources:
+ requests:
+ memory: "${ANSIBLE_MEM_REQ}"
+ cpu: "${ANSIBLE_CPU_REQ}"
+ limits:
+ memory: "${ANSIBLE_MEM_LIMIT}"
+ serviceAccount: cfme-privileged
+ serviceAccountName: cfme-privileged
+- apiVersion: v1
+ kind: ConfigMap
+ metadata:
+ name: "${HTTPD_SERVICE_NAME}-configs"
+ data:
+ application.conf: |
+ # Timeout: The number of seconds before receives and sends time out.
+ Timeout 120
+
+ RewriteEngine On
+ Options SymLinksIfOwnerMatch
+
+ <VirtualHost *:80>
+ KeepAlive on
+ # Without ServerName mod_auth_mellon compares against http:// and not https:// from the IdP
+ ServerName https://%{REQUEST_HOST}
+
+ ProxyPreserveHost on
+
+ RewriteCond %{REQUEST_URI} ^/ws [NC]
+ RewriteCond %{HTTP:UPGRADE} ^websocket$ [NC]
+ RewriteCond %{HTTP:CONNECTION} ^Upgrade$ [NC]
+ RewriteRule .* ws://${NAME}%{REQUEST_URI} [P,QSA,L]
+
+ # For httpd, some ErrorDocuments must by served by the httpd pod
+ RewriteCond %{REQUEST_URI} !^/proxy_pages
+
+ # For SAML /saml2 is only served by mod_auth_mellon in the httpd pod
+ RewriteCond %{REQUEST_URI} !^/saml2
+ RewriteRule ^/ http://${NAME}%{REQUEST_URI} [P,QSA,L]
+ ProxyPassReverse / http://${NAME}/
+
+ # Ensures httpd stdout/stderr are seen by docker logs.
+ ErrorLog "| /usr/bin/tee /proc/1/fd/2 /var/log/httpd/error_log"
+ CustomLog "| /usr/bin/tee /proc/1/fd/1 /var/log/httpd/access_log" common
+ </VirtualHost>
+ authentication.conf: |
+ # Load appropriate authentication configuration files
+ #
+ Include "conf.d/configuration-${HTTPD_AUTH_TYPE}-auth"
+ configuration-internal-auth: |
+ # Internal authentication
+ #
+ configuration-external-auth: |
+ Include "conf.d/external-auth-load-modules-conf"
+
+ <Location /dashboard/kerberos_authenticate>
+ AuthType Kerberos
+ AuthName "Kerberos Login"
+ KrbMethodNegotiate On
+ KrbMethodK5Passwd Off
+ KrbAuthRealms ${HTTPD_AUTH_KERBEROS_REALMS}
+ Krb5KeyTab /etc/http.keytab
+ KrbServiceName Any
+ Require pam-account httpd-auth
+
+ ErrorDocument 401 /proxy_pages/invalid_sso_credentials.js
+ </Location>
+
+ Include "conf.d/external-auth-login-form-conf"
+ Include "conf.d/external-auth-application-api-conf"
+ Include "conf.d/external-auth-lookup-user-details-conf"
+ Include "conf.d/external-auth-remote-user-conf"
+ configuration-active-directory-auth: |
+ Include "conf.d/external-auth-load-modules-conf"
+
+ <Location /dashboard/kerberos_authenticate>
+ AuthType Kerberos
+ AuthName "Kerberos Login"
+ KrbMethodNegotiate On
+ KrbMethodK5Passwd Off
+ KrbAuthRealms ${HTTPD_AUTH_KERBEROS_REALMS}
+ Krb5KeyTab /etc/krb5.keytab
+ KrbServiceName Any
+ Require pam-account httpd-auth
+
+ ErrorDocument 401 /proxy_pages/invalid_sso_credentials.js
+ </Location>
+
+ Include "conf.d/external-auth-login-form-conf"
+ Include "conf.d/external-auth-application-api-conf"
+ Include "conf.d/external-auth-lookup-user-details-conf"
+ Include "conf.d/external-auth-remote-user-conf"
+ configuration-saml-auth: |
+ LoadModule auth_mellon_module modules/mod_auth_mellon.so
+
+ <Location />
+ MellonEnable "info"
+
+ MellonIdPMetadataFile "/etc/httpd/saml2/idp-metadata.xml"
+
+ MellonSPPrivateKeyFile "/etc/httpd/saml2/sp-key.key"
+ MellonSPCertFile "/etc/httpd/saml2/sp-cert.cert"
+ MellonSPMetadataFile "/etc/httpd/saml2/sp-metadata.xml"
+
+ MellonVariable "sp-cookie"
+ MellonSecureCookie On
+ MellonCookiePath "/"
+
+ MellonIdP "IDP"
+
+ MellonEndpointPath "/saml2"
+
+ MellonUser username
+ MellonMergeEnvVars On
+
+ MellonSetEnvNoPrefix "REMOTE_USER" username
+ MellonSetEnvNoPrefix "REMOTE_USER_EMAIL" email
+ MellonSetEnvNoPrefix "REMOTE_USER_FIRSTNAME" firstname
+ MellonSetEnvNoPrefix "REMOTE_USER_LASTNAME" lastname
+ MellonSetEnvNoPrefix "REMOTE_USER_FULLNAME" fullname
+ MellonSetEnvNoPrefix "REMOTE_USER_GROUPS" groups
+ </Location>
+
+ <Location /saml_login>
+ AuthType "Mellon"
+ MellonEnable "auth"
+ Require valid-user
+ </Location>
+
+ Include "conf.d/external-auth-remote-user-conf"
+ external-auth-load-modules-conf: |
+ LoadModule authnz_pam_module modules/mod_authnz_pam.so
+ LoadModule intercept_form_submit_module modules/mod_intercept_form_submit.so
+ LoadModule lookup_identity_module modules/mod_lookup_identity.so
+ LoadModule auth_kerb_module modules/mod_auth_kerb.so
+ external-auth-login-form-conf: |
+ <Location /dashboard/external_authenticate>
+ InterceptFormPAMService httpd-auth
+ InterceptFormLogin user_name
+ InterceptFormPassword user_password
+ InterceptFormLoginSkip admin
+ InterceptFormClearRemoteUserForSkipped on
+ </Location>
+ external-auth-application-api-conf: |
+ <LocationMatch ^/api>
+ SetEnvIf Authorization '^Basic +YWRtaW46' let_admin_in
+ SetEnvIf X-Auth-Token '^.+$' let_api_token_in
+ SetEnvIf X-MIQ-Token '^.+$' let_sys_token_in
+
+ AuthType Basic
+ AuthName "External Authentication (httpd) for API"
+ AuthBasicProvider PAM
+
+ AuthPAMService httpd-auth
+ Require valid-user
+ Order Allow,Deny
+ Allow from env=let_admin_in
+ Allow from env=let_api_token_in
+ Allow from env=let_sys_token_in
+ Satisfy Any
+ </LocationMatch>
+ external-auth-lookup-user-details-conf: |
+ <LocationMatch ^/dashboard/external_authenticate$|^/dashboard/kerberos_authenticate$|^/api>
+ LookupUserAttr mail REMOTE_USER_EMAIL
+ LookupUserAttr givenname REMOTE_USER_FIRSTNAME
+ LookupUserAttr sn REMOTE_USER_LASTNAME
+ LookupUserAttr displayname REMOTE_USER_FULLNAME
+ LookupUserAttr domainname REMOTE_USER_DOMAIN
+
+ LookupUserGroups REMOTE_USER_GROUPS ":"
+ LookupDbusTimeout 5000
+ </LocationMatch>
+ external-auth-remote-user-conf: |
+ RequestHeader unset X_REMOTE_USER
+
+ RequestHeader set X_REMOTE_USER %{REMOTE_USER}e env=REMOTE_USER
+ RequestHeader set X_EXTERNAL_AUTH_ERROR %{EXTERNAL_AUTH_ERROR}e env=EXTERNAL_AUTH_ERROR
+ RequestHeader set X_REMOTE_USER_EMAIL %{REMOTE_USER_EMAIL}e env=REMOTE_USER_EMAIL
+ RequestHeader set X_REMOTE_USER_FIRSTNAME %{REMOTE_USER_FIRSTNAME}e env=REMOTE_USER_FIRSTNAME
+ RequestHeader set X_REMOTE_USER_LASTNAME %{REMOTE_USER_LASTNAME}e env=REMOTE_USER_LASTNAME
+ RequestHeader set X_REMOTE_USER_FULLNAME %{REMOTE_USER_FULLNAME}e env=REMOTE_USER_FULLNAME
+ RequestHeader set X_REMOTE_USER_GROUPS %{REMOTE_USER_GROUPS}e env=REMOTE_USER_GROUPS
+ RequestHeader set X_REMOTE_USER_DOMAIN %{REMOTE_USER_DOMAIN}e env=REMOTE_USER_DOMAIN
+- apiVersion: v1
+ kind: ConfigMap
+ metadata:
+ name: "${HTTPD_SERVICE_NAME}-auth-configs"
+ data:
+ auth-type: internal
+ auth-kerberos-realms: undefined
+ auth-configuration.conf: |
+ # External Authentication Configuration File
+ #
+ # For details on usage please see https://github.com/ManageIQ/manageiq-pods/blob/master/README.md#configuring-external-authentication
+- apiVersion: v1
+ kind: Service
+ metadata:
+ name: "${HTTPD_SERVICE_NAME}"
+ annotations:
+ description: Exposes the httpd server
+ service.alpha.openshift.io/dependencies: '[{"name":"${NAME}","namespace":"","kind":"Service"}]'
+ spec:
+ ports:
+ - name: http
+ port: 80
+ targetPort: 80
+ selector:
+ name: httpd
+- apiVersion: v1
+ kind: Service
+ metadata:
+ name: "${HTTPD_DBUS_API_SERVICE_NAME}"
+ annotations:
+ description: Exposes the httpd server dbus api
+ service.alpha.openshift.io/dependencies: '[{"name":"${NAME}","namespace":"","kind":"Service"}]'
+ spec:
+ ports:
+ - name: http-dbus-api
+ port: 8080
+ targetPort: 8080
+ selector:
+ name: httpd
+- apiVersion: v1
+ kind: DeploymentConfig
+ metadata:
+ name: "${HTTPD_SERVICE_NAME}"
+ annotations:
+ description: Defines how to deploy httpd
+ spec:
+ strategy:
+ type: Recreate
+ recreateParams:
+ timeoutSeconds: 1200
+ triggers:
+ - type: ConfigChange
+ replicas: 1
+ selector:
+ name: "${HTTPD_SERVICE_NAME}"
+ template:
+ metadata:
+ name: "${HTTPD_SERVICE_NAME}"
+ labels:
+ name: "${HTTPD_SERVICE_NAME}"
+ spec:
+ volumes:
+ - name: httpd-config
+ configMap:
+ name: "${HTTPD_SERVICE_NAME}-configs"
+ - name: httpd-auth-config
+ configMap:
+ name: "${HTTPD_SERVICE_NAME}-auth-configs"
+ containers:
+ - name: httpd
+ image: "${HTTPD_IMG_NAME}:${HTTPD_IMG_TAG}"
+ ports:
+ - containerPort: 80
+ protocol: TCP
+ - containerPort: 8080
+ protocol: TCP
+ livenessProbe:
+ exec:
+ command:
+ - pidof
+ - httpd
+ initialDelaySeconds: 15
+ timeoutSeconds: 3
+ readinessProbe:
+ tcpSocket:
+ port: 80
+ initialDelaySeconds: 10
+ timeoutSeconds: 3
+ volumeMounts:
+ - name: httpd-config
+ mountPath: "${HTTPD_CONFIG_DIR}"
+ - name: httpd-auth-config
+ mountPath: "${HTTPD_AUTH_CONFIG_DIR}"
+ resources:
+ requests:
+ memory: "${HTTPD_MEM_REQ}"
+ cpu: "${HTTPD_CPU_REQ}"
+ limits:
+ memory: "${HTTPD_MEM_LIMIT}"
+ env:
+ - name: HTTPD_AUTH_TYPE
+ valueFrom:
+ configMapKeyRef:
+ name: "${HTTPD_SERVICE_NAME}-auth-configs"
+ key: auth-type
+ - name: HTTPD_AUTH_KERBEROS_REALMS
+ valueFrom:
+ configMapKeyRef:
+ name: "${HTTPD_SERVICE_NAME}-auth-configs"
+ key: auth-kerberos-realms
+ lifecycle:
+ postStart:
+ exec:
+ command:
+ - "/usr/bin/save-container-environment"
+ serviceAccount: cfme-httpd
+ serviceAccountName: cfme-httpd
+parameters:
+- name: NAME
+ displayName: Name
+ required: true
+ description: The name assigned to all of the frontend objects defined in this template.
+ value: cloudforms
+- name: V2_KEY
+ displayName: CloudForms Encryption Key
+ required: true
+ description: Encryption Key for CloudForms Passwords
+ from: "[a-zA-Z0-9]{43}"
+ generate: expression
+- name: DATABASE_SERVICE_NAME
+ displayName: PostgreSQL Service Name
+ required: true
+ description: The name of the OpenShift Service exposed for the PostgreSQL container.
+ value: postgresql
+- name: DATABASE_USER
+ displayName: PostgreSQL User
+ required: true
+ description: PostgreSQL user that will access the database.
+ value: root
+- name: DATABASE_PASSWORD
+ displayName: PostgreSQL Password
+ required: true
+ description: Password for the PostgreSQL user.
+ from: "[a-zA-Z0-9]{8}"
+ generate: expression
+- name: DATABASE_IP
+ displayName: PostgreSQL Server IP
+ required: true
+ description: PostgreSQL external server IP used to configure service.
+ value: ''
+- name: DATABASE_PORT
+ displayName: PostgreSQL Server Port
+ required: true
+ description: PostgreSQL external server port used to configure service.
+ value: '5432'
+- name: DATABASE_NAME
+ required: true
+ displayName: PostgreSQL Database Name
+ description: Name of the PostgreSQL database accessed.
+ value: vmdb_production
+- name: DATABASE_REGION
+ required: true
+ displayName: Application Database Region
+ description: Database region that will be used for application.
+ value: '0'
+- name: APPLICATION_ADMIN_PASSWORD
+ displayName: Application Admin Password
+ required: true
+ description: Admin password that will be set on the application.
+ value: smartvm
+- name: ANSIBLE_DATABASE_NAME
+ displayName: Ansible PostgreSQL database name
+ required: true
+ description: The database to be used by the Ansible continer
+ value: awx
+- name: MEMCACHED_SERVICE_NAME
+ required: true
+ displayName: Memcached Service Name
+ description: The name of the OpenShift Service exposed for the Memcached container.
+ value: memcached
+- name: MEMCACHED_MAX_MEMORY
+ displayName: Memcached Max Memory
+ description: Memcached maximum memory for memcached object storage in MB.
+ value: '64'
+- name: MEMCACHED_MAX_CONNECTIONS
+ displayName: Memcached Max Connections
+ description: Memcached maximum number of connections allowed.
+ value: '1024'
+- name: MEMCACHED_SLAB_PAGE_SIZE
+ displayName: Memcached Slab Page Size
+ description: Memcached size of each slab page.
+ value: 1m
+- name: ANSIBLE_SERVICE_NAME
+ displayName: Ansible Service Name
+ description: The name of the OpenShift Service exposed for the Ansible container.
+ value: ansible
+- name: ANSIBLE_ADMIN_PASSWORD
+ displayName: Ansible admin User password
+ required: true
+ description: The password for the Ansible container admin user
+ from: "[a-zA-Z0-9]{32}"
+ generate: expression
+- name: ANSIBLE_SECRET_KEY
+ displayName: Ansible Secret Key
+ required: true
+ description: Encryption key for the Ansible container
+ from: "[a-f0-9]{32}"
+ generate: expression
+- name: ANSIBLE_RABBITMQ_USER_NAME
+ displayName: RabbitMQ Username
+ required: true
+ description: Username for the Ansible RabbitMQ Server
+ value: ansible
+- name: ANSIBLE_RABBITMQ_PASSWORD
+ displayName: RabbitMQ Server Password
+ required: true
+ description: Password for the Ansible RabbitMQ Server
+ from: "[a-zA-Z0-9]{32}"
+ generate: expression
+- name: APPLICATION_CPU_REQ
+ displayName: Application Min CPU Requested
+ required: true
+ description: Minimum amount of CPU time the Application container will need (expressed in millicores).
+ value: 1000m
+- name: MEMCACHED_CPU_REQ
+ displayName: Memcached Min CPU Requested
+ required: true
+ description: Minimum amount of CPU time the Memcached container will need (expressed in millicores).
+ value: 200m
+- name: ANSIBLE_CPU_REQ
+ displayName: Ansible Min CPU Requested
+ required: true
+ description: Minimum amount of CPU time the Ansible container will need (expressed in millicores).
+ value: 1000m
+- name: APPLICATION_MEM_REQ
+ displayName: Application Min RAM Requested
+ required: true
+ description: Minimum amount of memory the Application container will need.
+ value: 6144Mi
+- name: MEMCACHED_MEM_REQ
+ displayName: Memcached Min RAM Requested
+ required: true
+ description: Minimum amount of memory the Memcached container will need.
+ value: 64Mi
+- name: ANSIBLE_MEM_REQ
+ displayName: Ansible Min RAM Requested
+ required: true
+ description: Minimum amount of memory the Ansible container will need.
+ value: 2048Mi
+- name: APPLICATION_MEM_LIMIT
+ displayName: Application Max RAM Limit
+ required: true
+ description: Maximum amount of memory the Application container can consume.
+ value: 16384Mi
+- name: MEMCACHED_MEM_LIMIT
+ displayName: Memcached Max RAM Limit
+ required: true
+ description: Maximum amount of memory the Memcached container can consume.
+ value: 256Mi
+- name: ANSIBLE_MEM_LIMIT
+ displayName: Ansible Max RAM Limit
+ required: true
+ description: Maximum amount of memory the Ansible container can consume.
+ value: 8096Mi
+- name: MEMCACHED_IMG_NAME
+ displayName: Memcached Image Name
+ description: This is the Memcached image name requested to deploy.
+ value: registry.access.redhat.com/cloudforms46-beta/cfme-openshift-memcached
+- name: MEMCACHED_IMG_TAG
+ displayName: Memcached Image Tag
+ description: This is the Memcached image tag/version requested to deploy.
+ value: latest
+- name: FRONTEND_APPLICATION_IMG_NAME
+ displayName: Frontend Application Image Name
+ description: This is the Frontend Application image name requested to deploy.
+ value: registry.access.redhat.com/cloudforms46-beta/cfme-openshift-app-ui
+- name: BACKEND_APPLICATION_IMG_NAME
+ displayName: Backend Application Image Name
+ description: This is the Backend Application image name requested to deploy.
+ value: registry.access.redhat.com/cloudforms46-beta/cfme-openshift-app
+- name: FRONTEND_APPLICATION_IMG_TAG
+ displayName: Front end Application Image Tag
+ description: This is the CloudForms Frontend Application image tag/version requested to deploy.
+ value: latest
+- name: BACKEND_APPLICATION_IMG_TAG
+ displayName: Back end Application Image Tag
+ description: This is the CloudForms Backend Application image tag/version requested to deploy.
+ value: latest
+- name: ANSIBLE_IMG_NAME
+ displayName: Ansible Image Name
+ description: This is the Ansible image name requested to deploy.
+ value: registry.access.redhat.com/cloudforms46-beta/cfme-openshift-embedded-ansible
+- name: ANSIBLE_IMG_TAG
+ displayName: Ansible Image Tag
+ description: This is the Ansible image tag/version requested to deploy.
+ value: latest
+- name: APPLICATION_DOMAIN
+ displayName: Application Hostname
+ description: The exposed hostname that will route to the application service, if left blank a value will be defaulted.
+ value: ''
+- name: APPLICATION_REPLICA_COUNT
+ displayName: Application Replica Count
+ description: This is the number of Application replicas requested to deploy.
+ value: '1'
+- name: APPLICATION_INIT_DELAY
+ displayName: Application Init Delay
+ required: true
+ description: Delay in seconds before we attempt to initialize the application.
+ value: '15'
+- name: APPLICATION_VOLUME_CAPACITY
+ displayName: Application Volume Capacity
+ required: true
+ description: Volume space available for application data.
+ value: 5Gi
+- name: HTTPD_SERVICE_NAME
+ required: true
+ displayName: Apache httpd Service Name
+ description: The name of the OpenShift Service exposed for the httpd container.
+ value: httpd
+- name: HTTPD_DBUS_API_SERVICE_NAME
+ required: true
+ displayName: Apache httpd DBus API Service Name
+ description: The name of httpd dbus api service.
+ value: httpd-dbus-api
+- name: HTTPD_IMG_NAME
+ displayName: Apache httpd Image Name
+ description: This is the httpd image name requested to deploy.
+ value: registry.access.redhat.com/cloudforms46-beta/cfme-openshift-httpd
+- name: HTTPD_IMG_TAG
+ displayName: Apache httpd Image Tag
+ description: This is the httpd image tag/version requested to deploy.
+ value: latest
+- name: HTTPD_CONFIG_DIR
+ displayName: Apache httpd Configuration Directory
+ description: Directory used to store the Apache configuration files.
+ value: "/etc/httpd/conf.d"
+- name: HTTPD_AUTH_CONFIG_DIR
+ displayName: External Authentication Configuration Directory
+ description: Directory used to store the external authentication configuration files.
+ value: "/etc/httpd/auth-conf.d"
+- name: HTTPD_CPU_REQ
+ displayName: Apache httpd Min CPU Requested
+ required: true
+ description: Minimum amount of CPU time the httpd container will need (expressed in millicores).
+ value: 500m
+- name: HTTPD_MEM_REQ
+ displayName: Apache httpd Min RAM Requested
+ required: true
+ description: Minimum amount of memory the httpd container will need.
+ value: 512Mi
+- name: HTTPD_MEM_LIMIT
+ displayName: Apache httpd Max RAM Limit
+ required: true
+ description: Maximum amount of memory the httpd container can consume.
+ value: 8192Mi
diff --git a/roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-template.yaml b/roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-template.yaml
index 3bc6c5813..5c757b6c2 100644
--- a/roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-template.yaml
+++ b/roles/openshift_examples/files/examples/v3.7/cfme-templates/cfme-template.yaml
@@ -5,17 +5,308 @@ labels:
metadata:
name: cloudforms
annotations:
- description: "CloudForms appliance with persistent storage"
- tags: "instant-app,cloudforms,cfme"
- iconClass: "icon-rails"
+ description: CloudForms appliance with persistent storage
+ tags: instant-app,cloudforms,cfme
+ iconClass: icon-rails
objects:
- apiVersion: v1
+ kind: ServiceAccount
+ metadata:
+ name: cfme-orchestrator
+- apiVersion: v1
+ kind: ServiceAccount
+ metadata:
+ name: cfme-anyuid
+- apiVersion: v1
+ kind: ServiceAccount
+ metadata:
+ name: cfme-privileged
+- apiVersion: v1
+ kind: ServiceAccount
+ metadata:
+ name: cfme-httpd
+- apiVersion: v1
+ kind: Secret
+ metadata:
+ name: "${NAME}-secrets"
+ stringData:
+ pg-password: "${DATABASE_PASSWORD}"
+ admin-password: "${APPLICATION_ADMIN_PASSWORD}"
+ database-url: postgresql://${DATABASE_USER}:${DATABASE_PASSWORD}@${DATABASE_SERVICE_NAME}/${DATABASE_NAME}?encoding=utf8&pool=5&wait_timeout=5
+ v2-key: "${V2_KEY}"
+- apiVersion: v1
+ kind: Secret
+ metadata:
+ name: "${ANSIBLE_SERVICE_NAME}-secrets"
+ stringData:
+ rabbit-password: "${ANSIBLE_RABBITMQ_PASSWORD}"
+ secret-key: "${ANSIBLE_SECRET_KEY}"
+ admin-password: "${ANSIBLE_ADMIN_PASSWORD}"
+- apiVersion: v1
+ kind: ConfigMap
+ metadata:
+ name: "${DATABASE_SERVICE_NAME}-configs"
+ data:
+ 01_miq_overrides.conf: |
+ #------------------------------------------------------------------------------
+ # CONNECTIONS AND AUTHENTICATION
+ #------------------------------------------------------------------------------
+
+ tcp_keepalives_count = 9
+ tcp_keepalives_idle = 3
+ tcp_keepalives_interval = 75
+
+ #------------------------------------------------------------------------------
+ # RESOURCE USAGE (except WAL)
+ #------------------------------------------------------------------------------
+
+ shared_preload_libraries = 'pglogical,repmgr_funcs'
+ max_worker_processes = 10
+
+ #------------------------------------------------------------------------------
+ # WRITE AHEAD LOG
+ #------------------------------------------------------------------------------
+
+ wal_level = 'logical'
+ wal_log_hints = on
+ wal_buffers = 16MB
+ checkpoint_completion_target = 0.9
+
+ #------------------------------------------------------------------------------
+ # REPLICATION
+ #------------------------------------------------------------------------------
+
+ max_wal_senders = 10
+ wal_sender_timeout = 0
+ max_replication_slots = 10
+ hot_standby = on
+
+ #------------------------------------------------------------------------------
+ # ERROR REPORTING AND LOGGING
+ #------------------------------------------------------------------------------
+
+ log_filename = 'postgresql.log'
+ log_rotation_age = 0
+ log_min_duration_statement = 5000
+ log_connections = on
+ log_disconnections = on
+ log_line_prefix = '%t:%r:%c:%u@%d:[%p]:'
+ log_lock_waits = on
+
+ #------------------------------------------------------------------------------
+ # AUTOVACUUM PARAMETERS
+ #------------------------------------------------------------------------------
+
+ log_autovacuum_min_duration = 0
+ autovacuum_naptime = 5min
+ autovacuum_vacuum_threshold = 500
+ autovacuum_analyze_threshold = 500
+ autovacuum_vacuum_scale_factor = 0.05
+
+ #------------------------------------------------------------------------------
+ # LOCK MANAGEMENT
+ #------------------------------------------------------------------------------
+
+ deadlock_timeout = 5s
+
+ #------------------------------------------------------------------------------
+ # VERSION/PLATFORM COMPATIBILITY
+ #------------------------------------------------------------------------------
+
+ escape_string_warning = off
+ standard_conforming_strings = off
+- apiVersion: v1
+ kind: ConfigMap
+ metadata:
+ name: "${HTTPD_SERVICE_NAME}-configs"
+ data:
+ application.conf: |
+ # Timeout: The number of seconds before receives and sends time out.
+ Timeout 120
+
+ RewriteEngine On
+ Options SymLinksIfOwnerMatch
+
+ <VirtualHost *:80>
+ KeepAlive on
+ # Without ServerName mod_auth_mellon compares against http:// and not https:// from the IdP
+ ServerName https://%{REQUEST_HOST}
+
+ ProxyPreserveHost on
+
+ RewriteCond %{REQUEST_URI} ^/ws [NC]
+ RewriteCond %{HTTP:UPGRADE} ^websocket$ [NC]
+ RewriteCond %{HTTP:CONNECTION} ^Upgrade$ [NC]
+ RewriteRule .* ws://${NAME}%{REQUEST_URI} [P,QSA,L]
+
+ # For httpd, some ErrorDocuments must by served by the httpd pod
+ RewriteCond %{REQUEST_URI} !^/proxy_pages
+
+ # For SAML /saml2 is only served by mod_auth_mellon in the httpd pod
+ RewriteCond %{REQUEST_URI} !^/saml2
+ RewriteRule ^/ http://${NAME}%{REQUEST_URI} [P,QSA,L]
+ ProxyPassReverse / http://${NAME}/
+
+ # Ensures httpd stdout/stderr are seen by docker logs.
+ ErrorLog "| /usr/bin/tee /proc/1/fd/2 /var/log/httpd/error_log"
+ CustomLog "| /usr/bin/tee /proc/1/fd/1 /var/log/httpd/access_log" common
+ </VirtualHost>
+ authentication.conf: |
+ # Load appropriate authentication configuration files
+ #
+ Include "conf.d/configuration-${HTTPD_AUTH_TYPE}-auth"
+ configuration-internal-auth: |
+ # Internal authentication
+ #
+ configuration-external-auth: |
+ Include "conf.d/external-auth-load-modules-conf"
+
+ <Location /dashboard/kerberos_authenticate>
+ AuthType Kerberos
+ AuthName "Kerberos Login"
+ KrbMethodNegotiate On
+ KrbMethodK5Passwd Off
+ KrbAuthRealms ${HTTPD_AUTH_KERBEROS_REALMS}
+ Krb5KeyTab /etc/http.keytab
+ KrbServiceName Any
+ Require pam-account httpd-auth
+
+ ErrorDocument 401 /proxy_pages/invalid_sso_credentials.js
+ </Location>
+
+ Include "conf.d/external-auth-login-form-conf"
+ Include "conf.d/external-auth-application-api-conf"
+ Include "conf.d/external-auth-lookup-user-details-conf"
+ Include "conf.d/external-auth-remote-user-conf"
+ configuration-active-directory-auth: |
+ Include "conf.d/external-auth-load-modules-conf"
+
+ <Location /dashboard/kerberos_authenticate>
+ AuthType Kerberos
+ AuthName "Kerberos Login"
+ KrbMethodNegotiate On
+ KrbMethodK5Passwd Off
+ KrbAuthRealms ${HTTPD_AUTH_KERBEROS_REALMS}
+ Krb5KeyTab /etc/krb5.keytab
+ KrbServiceName Any
+ Require pam-account httpd-auth
+
+ ErrorDocument 401 /proxy_pages/invalid_sso_credentials.js
+ </Location>
+
+ Include "conf.d/external-auth-login-form-conf"
+ Include "conf.d/external-auth-application-api-conf"
+ Include "conf.d/external-auth-lookup-user-details-conf"
+ Include "conf.d/external-auth-remote-user-conf"
+ configuration-saml-auth: |
+ LoadModule auth_mellon_module modules/mod_auth_mellon.so
+
+ <Location />
+ MellonEnable "info"
+
+ MellonIdPMetadataFile "/etc/httpd/saml2/idp-metadata.xml"
+
+ MellonSPPrivateKeyFile "/etc/httpd/saml2/sp-key.key"
+ MellonSPCertFile "/etc/httpd/saml2/sp-cert.cert"
+ MellonSPMetadataFile "/etc/httpd/saml2/sp-metadata.xml"
+
+ MellonVariable "sp-cookie"
+ MellonSecureCookie On
+ MellonCookiePath "/"
+
+ MellonIdP "IDP"
+
+ MellonEndpointPath "/saml2"
+
+ MellonUser username
+ MellonMergeEnvVars On
+
+ MellonSetEnvNoPrefix "REMOTE_USER" username
+ MellonSetEnvNoPrefix "REMOTE_USER_EMAIL" email
+ MellonSetEnvNoPrefix "REMOTE_USER_FIRSTNAME" firstname
+ MellonSetEnvNoPrefix "REMOTE_USER_LASTNAME" lastname
+ MellonSetEnvNoPrefix "REMOTE_USER_FULLNAME" fullname
+ MellonSetEnvNoPrefix "REMOTE_USER_GROUPS" groups
+ </Location>
+
+ <Location /saml_login>
+ AuthType "Mellon"
+ MellonEnable "auth"
+ Require valid-user
+ </Location>
+
+ Include "conf.d/external-auth-remote-user-conf"
+ external-auth-load-modules-conf: |
+ LoadModule authnz_pam_module modules/mod_authnz_pam.so
+ LoadModule intercept_form_submit_module modules/mod_intercept_form_submit.so
+ LoadModule lookup_identity_module modules/mod_lookup_identity.so
+ LoadModule auth_kerb_module modules/mod_auth_kerb.so
+ external-auth-login-form-conf: |
+ <Location /dashboard/external_authenticate>
+ InterceptFormPAMService httpd-auth
+ InterceptFormLogin user_name
+ InterceptFormPassword user_password
+ InterceptFormLoginSkip admin
+ InterceptFormClearRemoteUserForSkipped on
+ </Location>
+ external-auth-application-api-conf: |
+ <LocationMatch ^/api>
+ SetEnvIf Authorization '^Basic +YWRtaW46' let_admin_in
+ SetEnvIf X-Auth-Token '^.+$' let_api_token_in
+ SetEnvIf X-MIQ-Token '^.+$' let_sys_token_in
+
+ AuthType Basic
+ AuthName "External Authentication (httpd) for API"
+ AuthBasicProvider PAM
+
+ AuthPAMService httpd-auth
+ Require valid-user
+ Order Allow,Deny
+ Allow from env=let_admin_in
+ Allow from env=let_api_token_in
+ Allow from env=let_sys_token_in
+ Satisfy Any
+ </LocationMatch>
+ external-auth-lookup-user-details-conf: |
+ <LocationMatch ^/dashboard/external_authenticate$|^/dashboard/kerberos_authenticate$|^/api>
+ LookupUserAttr mail REMOTE_USER_EMAIL
+ LookupUserAttr givenname REMOTE_USER_FIRSTNAME
+ LookupUserAttr sn REMOTE_USER_LASTNAME
+ LookupUserAttr displayname REMOTE_USER_FULLNAME
+ LookupUserAttr domainname REMOTE_USER_DOMAIN
+
+ LookupUserGroups REMOTE_USER_GROUPS ":"
+ LookupDbusTimeout 5000
+ </LocationMatch>
+ external-auth-remote-user-conf: |
+ RequestHeader unset X_REMOTE_USER
+
+ RequestHeader set X_REMOTE_USER %{REMOTE_USER}e env=REMOTE_USER
+ RequestHeader set X_EXTERNAL_AUTH_ERROR %{EXTERNAL_AUTH_ERROR}e env=EXTERNAL_AUTH_ERROR
+ RequestHeader set X_REMOTE_USER_EMAIL %{REMOTE_USER_EMAIL}e env=REMOTE_USER_EMAIL
+ RequestHeader set X_REMOTE_USER_FIRSTNAME %{REMOTE_USER_FIRSTNAME}e env=REMOTE_USER_FIRSTNAME
+ RequestHeader set X_REMOTE_USER_LASTNAME %{REMOTE_USER_LASTNAME}e env=REMOTE_USER_LASTNAME
+ RequestHeader set X_REMOTE_USER_FULLNAME %{REMOTE_USER_FULLNAME}e env=REMOTE_USER_FULLNAME
+ RequestHeader set X_REMOTE_USER_GROUPS %{REMOTE_USER_GROUPS}e env=REMOTE_USER_GROUPS
+ RequestHeader set X_REMOTE_USER_DOMAIN %{REMOTE_USER_DOMAIN}e env=REMOTE_USER_DOMAIN
+- apiVersion: v1
+ kind: ConfigMap
+ metadata:
+ name: "${HTTPD_SERVICE_NAME}-auth-configs"
+ data:
+ auth-type: internal
+ auth-kerberos-realms: undefined
+ auth-configuration.conf: |
+ # External Authentication Configuration File
+ #
+ # For details on usage please see https://github.com/ManageIQ/manageiq-pods/blob/master/README.md#configuring-external-authentication
+- apiVersion: v1
kind: Service
metadata:
annotations:
- description: "Exposes and load balances CloudForms pods"
+ description: Exposes and load balances CloudForms pods
service.alpha.openshift.io/dependencies: '[{"name":"${DATABASE_SERVICE_NAME}","namespace":"","kind":"Service"},{"name":"${MEMCACHED_SERVICE_NAME}","namespace":"","kind":"Service"}]'
- name: ${NAME}
+ name: "${NAME}"
spec:
clusterIP: None
ports:
@@ -23,141 +314,97 @@ objects:
port: 80
protocol: TCP
targetPort: 80
- - name: https
- port: 443
- protocol: TCP
- targetPort: 443
selector:
- name: ${NAME}
+ name: "${NAME}"
- apiVersion: v1
kind: Route
metadata:
- name: ${NAME}
+ name: "${HTTPD_SERVICE_NAME}"
spec:
- host: ${APPLICATION_DOMAIN}
+ host: "${APPLICATION_DOMAIN}"
port:
- targetPort: https
+ targetPort: http
tls:
- termination: passthrough
+ termination: edge
+ insecureEdgeTerminationPolicy: Redirect
to:
kind: Service
- name: ${NAME}
-- apiVersion: v1
- kind: ImageStream
- metadata:
- name: cfme-openshift-app
- annotations:
- description: "Keeps track of changes in the CloudForms app image"
- spec:
- dockerImageRepository: "${APPLICATION_IMG_NAME}"
-- apiVersion: v1
- kind: ImageStream
- metadata:
- name: cfme-openshift-postgresql
- annotations:
- description: "Keeps track of changes in the CloudForms postgresql image"
- spec:
- dockerImageRepository: "${POSTGRESQL_IMG_NAME}"
-- apiVersion: v1
- kind: ImageStream
- metadata:
- name: cfme-openshift-memcached
- annotations:
- description: "Keeps track of changes in the CloudForms memcached image"
- spec:
- dockerImageRepository: "${MEMCACHED_IMG_NAME}"
+ name: "${HTTPD_SERVICE_NAME}"
- apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: "${NAME}-${DATABASE_SERVICE_NAME}"
spec:
accessModes:
- - ReadWriteOnce
+ - ReadWriteOnce
resources:
requests:
- storage: ${DATABASE_VOLUME_CAPACITY}
-- apiVersion: v1
- kind: PersistentVolumeClaim
- metadata:
- name: "${NAME}-region"
- spec:
- accessModes:
- - ReadWriteOnce
- resources:
- requests:
- storage: ${APPLICATION_REGION_VOLUME_CAPACITY}
+ storage: "${DATABASE_VOLUME_CAPACITY}"
- apiVersion: apps/v1beta1
- kind: "StatefulSet"
+ kind: StatefulSet
metadata:
- name: ${NAME}
+ name: "${NAME}"
annotations:
- description: "Defines how to deploy the CloudForms appliance"
+ description: Defines how to deploy the CloudForms appliance
spec:
serviceName: "${NAME}"
- replicas: 1
+ replicas: "${APPLICATION_REPLICA_COUNT}"
template:
metadata:
labels:
- name: ${NAME}
- name: ${NAME}
+ name: "${NAME}"
+ name: "${NAME}"
spec:
containers:
- name: cloudforms
- image: "${APPLICATION_IMG_NAME}:${APPLICATION_IMG_TAG}"
+ image: "${FRONTEND_APPLICATION_IMG_NAME}:${FRONTEND_APPLICATION_IMG_TAG}"
livenessProbe:
- tcpSocket:
- port: 443
+ exec:
+ command:
+ - pidof
+ - MIQ Server
initialDelaySeconds: 480
timeoutSeconds: 3
readinessProbe:
- httpGet:
- path: /
- port: 443
- scheme: HTTPS
+ tcpSocket:
+ port: 80
initialDelaySeconds: 200
timeoutSeconds: 3
ports:
- containerPort: 80
protocol: TCP
- - containerPort: 443
- protocol: TCP
- securityContext:
- privileged: true
volumeMounts:
- -
- name: "${NAME}-server"
- mountPath: "/persistent"
- -
- name: "${NAME}-region"
- mountPath: "/persistent-region"
+ - name: "${NAME}-server"
+ mountPath: "/persistent"
env:
- -
- name: "APPLICATION_INIT_DELAY"
- value: "${APPLICATION_INIT_DELAY}"
- -
- name: "DATABASE_SERVICE_NAME"
- value: "${DATABASE_SERVICE_NAME}"
- -
- name: "DATABASE_REGION"
- value: "${DATABASE_REGION}"
- -
- name: "MEMCACHED_SERVICE_NAME"
- value: "${MEMCACHED_SERVICE_NAME}"
- -
- name: "POSTGRESQL_USER"
- value: "${DATABASE_USER}"
- -
- name: "POSTGRESQL_PASSWORD"
- value: "${DATABASE_PASSWORD}"
- -
- name: "POSTGRESQL_DATABASE"
- value: "${DATABASE_NAME}"
- -
- name: "POSTGRESQL_MAX_CONNECTIONS"
- value: "${POSTGRESQL_MAX_CONNECTIONS}"
- -
- name: "POSTGRESQL_SHARED_BUFFERS"
- value: "${POSTGRESQL_SHARED_BUFFERS}"
+ - name: MY_POD_NAMESPACE
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.namespace
+ - name: APPLICATION_INIT_DELAY
+ value: "${APPLICATION_INIT_DELAY}"
+ - name: DATABASE_REGION
+ value: "${DATABASE_REGION}"
+ - name: DATABASE_URL
+ valueFrom:
+ secretKeyRef:
+ name: "${NAME}-secrets"
+ key: database-url
+ - name: V2_KEY
+ valueFrom:
+ secretKeyRef:
+ name: "${NAME}-secrets"
+ key: v2-key
+ - name: APPLICATION_ADMIN_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: "${NAME}-secrets"
+ key: admin-password
+ - name: ANSIBLE_ADMIN_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: "${ANSIBLE_SERVICE_NAME}-secrets"
+ key: admin-password
resources:
requests:
memory: "${APPLICATION_MEM_REQ}"
@@ -168,59 +415,128 @@ objects:
preStop:
exec:
command:
- - /opt/rh/cfme-container-scripts/sync-pv-data
- volumes:
- -
- name: "${NAME}-region"
- persistentVolumeClaim:
- claimName: ${NAME}-region
+ - "/opt/rh/cfme-container-scripts/sync-pv-data"
+ serviceAccount: cfme-orchestrator
+ serviceAccountName: cfme-orchestrator
+ terminationGracePeriodSeconds: 90
volumeClaimTemplates:
- - metadata:
- name: "${NAME}-server"
- annotations:
- # Uncomment this if using dynamic volume provisioning.
- # https://docs.openshift.org/latest/install_config/persistent_storage/dynamically_provisioning_pvs.html
- # volume.alpha.kubernetes.io/storage-class: anything
- spec:
- accessModes: [ ReadWriteOnce ]
+ - metadata:
+ name: "${NAME}-server"
+ annotations:
+ spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: "${APPLICATION_VOLUME_CAPACITY}"
+- apiVersion: v1
+ kind: Service
+ metadata:
+ annotations:
+ description: Headless service for CloudForms backend pods
+ name: "${NAME}-backend"
+ spec:
+ clusterIP: None
+ selector:
+ name: "${NAME}-backend"
+- apiVersion: apps/v1beta1
+ kind: StatefulSet
+ metadata:
+ name: "${NAME}-backend"
+ annotations:
+ description: Defines how to deploy the CloudForms appliance
+ spec:
+ serviceName: "${NAME}-backend"
+ replicas: 0
+ template:
+ metadata:
+ labels:
+ name: "${NAME}-backend"
+ name: "${NAME}-backend"
+ spec:
+ containers:
+ - name: cloudforms
+ image: "${BACKEND_APPLICATION_IMG_NAME}:${BACKEND_APPLICATION_IMG_TAG}"
+ livenessProbe:
+ exec:
+ command:
+ - pidof
+ - MIQ Server
+ initialDelaySeconds: 480
+ timeoutSeconds: 3
+ volumeMounts:
+ - name: "${NAME}-server"
+ mountPath: "/persistent"
+ env:
+ - name: APPLICATION_INIT_DELAY
+ value: "${APPLICATION_INIT_DELAY}"
+ - name: DATABASE_URL
+ valueFrom:
+ secretKeyRef:
+ name: "${NAME}-secrets"
+ key: database-url
+ - name: MIQ_SERVER_DEFAULT_ROLES
+ value: database_operations,event,reporting,scheduler,smartstate,ems_operations,ems_inventory,automate
+ - name: FRONTEND_SERVICE_NAME
+ value: "${NAME}"
+ - name: V2_KEY
+ valueFrom:
+ secretKeyRef:
+ name: "${NAME}-secrets"
+ key: v2-key
+ - name: ANSIBLE_ADMIN_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: "${ANSIBLE_SERVICE_NAME}-secrets"
+ key: admin-password
resources:
requests:
- storage: "${APPLICATION_VOLUME_CAPACITY}"
+ memory: "${APPLICATION_MEM_REQ}"
+ cpu: "${APPLICATION_CPU_REQ}"
+ limits:
+ memory: "${APPLICATION_MEM_LIMIT}"
+ lifecycle:
+ preStop:
+ exec:
+ command:
+ - "/opt/rh/cfme-container-scripts/sync-pv-data"
+ serviceAccount: cfme-orchestrator
+ serviceAccountName: cfme-orchestrator
+ terminationGracePeriodSeconds: 90
+ volumeClaimTemplates:
+ - metadata:
+ name: "${NAME}-server"
+ annotations:
+ spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: "${APPLICATION_VOLUME_CAPACITY}"
- apiVersion: v1
- kind: "Service"
+ kind: Service
metadata:
name: "${MEMCACHED_SERVICE_NAME}"
annotations:
- description: "Exposes the memcached server"
+ description: Exposes the memcached server
spec:
ports:
- -
- name: "memcached"
- port: 11211
- targetPort: 11211
+ - name: memcached
+ port: 11211
+ targetPort: 11211
selector:
name: "${MEMCACHED_SERVICE_NAME}"
- apiVersion: v1
- kind: "DeploymentConfig"
+ kind: DeploymentConfig
metadata:
name: "${MEMCACHED_SERVICE_NAME}"
annotations:
- description: "Defines how to deploy memcached"
+ description: Defines how to deploy memcached
spec:
strategy:
- type: "Recreate"
+ type: Recreate
triggers:
- -
- type: "ImageChange"
- imageChangeParams:
- automatic: true
- containerNames:
- - "memcached"
- from:
- kind: "ImageStreamTag"
- name: "cfme-openshift-memcached:${MEMCACHED_IMG_TAG}"
- -
- type: "ConfigChange"
+ - type: ConfigChange
replicas: 1
selector:
name: "${MEMCACHED_SERVICE_NAME}"
@@ -232,74 +548,58 @@ objects:
spec:
volumes: []
containers:
- -
- name: "memcached"
- image: "${MEMCACHED_IMG_NAME}:${MEMCACHED_IMG_TAG}"
- ports:
- -
- containerPort: 11211
- readinessProbe:
- timeoutSeconds: 1
- initialDelaySeconds: 5
- tcpSocket:
- port: 11211
- livenessProbe:
- timeoutSeconds: 1
- initialDelaySeconds: 30
- tcpSocket:
- port: 11211
- volumeMounts: []
- env:
- -
- name: "MEMCACHED_MAX_MEMORY"
- value: "${MEMCACHED_MAX_MEMORY}"
- -
- name: "MEMCACHED_MAX_CONNECTIONS"
- value: "${MEMCACHED_MAX_CONNECTIONS}"
- -
- name: "MEMCACHED_SLAB_PAGE_SIZE"
- value: "${MEMCACHED_SLAB_PAGE_SIZE}"
- resources:
- requests:
- memory: "${MEMCACHED_MEM_REQ}"
- cpu: "${MEMCACHED_CPU_REQ}"
- limits:
- memory: "${MEMCACHED_MEM_LIMIT}"
+ - name: memcached
+ image: "${MEMCACHED_IMG_NAME}:${MEMCACHED_IMG_TAG}"
+ ports:
+ - containerPort: 11211
+ readinessProbe:
+ timeoutSeconds: 1
+ initialDelaySeconds: 5
+ tcpSocket:
+ port: 11211
+ livenessProbe:
+ timeoutSeconds: 1
+ initialDelaySeconds: 30
+ tcpSocket:
+ port: 11211
+ volumeMounts: []
+ env:
+ - name: MEMCACHED_MAX_MEMORY
+ value: "${MEMCACHED_MAX_MEMORY}"
+ - name: MEMCACHED_MAX_CONNECTIONS
+ value: "${MEMCACHED_MAX_CONNECTIONS}"
+ - name: MEMCACHED_SLAB_PAGE_SIZE
+ value: "${MEMCACHED_SLAB_PAGE_SIZE}"
+ resources:
+ requests:
+ memory: "${MEMCACHED_MEM_REQ}"
+ cpu: "${MEMCACHED_CPU_REQ}"
+ limits:
+ memory: "${MEMCACHED_MEM_LIMIT}"
- apiVersion: v1
- kind: "Service"
+ kind: Service
metadata:
name: "${DATABASE_SERVICE_NAME}"
annotations:
- description: "Exposes the database server"
+ description: Exposes the database server
spec:
ports:
- -
- name: "postgresql"
- port: 5432
- targetPort: 5432
+ - name: postgresql
+ port: 5432
+ targetPort: 5432
selector:
name: "${DATABASE_SERVICE_NAME}"
- apiVersion: v1
- kind: "DeploymentConfig"
+ kind: DeploymentConfig
metadata:
name: "${DATABASE_SERVICE_NAME}"
annotations:
- description: "Defines how to deploy the database"
+ description: Defines how to deploy the database
spec:
strategy:
- type: "Recreate"
+ type: Recreate
triggers:
- -
- type: "ImageChange"
- imageChangeParams:
- automatic: true
- containerNames:
- - "postgresql"
- from:
- kind: "ImageStreamTag"
- name: "cfme-openshift-postgresql:${POSTGRESQL_IMG_TAG}"
- -
- type: "ConfigChange"
+ - type: ConfigChange
replicas: 1
selector:
name: "${DATABASE_SERVICE_NAME}"
@@ -310,236 +610,524 @@ objects:
name: "${DATABASE_SERVICE_NAME}"
spec:
volumes:
- -
- name: "cfme-pgdb-volume"
- persistentVolumeClaim:
- claimName: "${NAME}-${DATABASE_SERVICE_NAME}"
+ - name: cfme-pgdb-volume
+ persistentVolumeClaim:
+ claimName: "${NAME}-${DATABASE_SERVICE_NAME}"
+ - name: cfme-pg-configs
+ configMap:
+ name: "${DATABASE_SERVICE_NAME}-configs"
containers:
- -
- name: "postgresql"
- image: "${POSTGRESQL_IMG_NAME}:${POSTGRESQL_IMG_TAG}"
- ports:
- -
- containerPort: 5432
- readinessProbe:
- timeoutSeconds: 1
- initialDelaySeconds: 15
+ - name: postgresql
+ image: "${POSTGRESQL_IMG_NAME}:${POSTGRESQL_IMG_TAG}"
+ ports:
+ - containerPort: 5432
+ readinessProbe:
+ timeoutSeconds: 1
+ initialDelaySeconds: 15
+ exec:
+ command:
+ - "/bin/sh"
+ - "-i"
+ - "-c"
+ - psql -h 127.0.0.1 -U ${POSTGRESQL_USER} -q -d ${POSTGRESQL_DATABASE} -c 'SELECT 1'
+ livenessProbe:
+ timeoutSeconds: 1
+ initialDelaySeconds: 60
+ tcpSocket:
+ port: 5432
+ volumeMounts:
+ - name: cfme-pgdb-volume
+ mountPath: "/var/lib/pgsql/data"
+ - name: cfme-pg-configs
+ mountPath: "${POSTGRESQL_CONFIG_DIR}"
+ env:
+ - name: POSTGRESQL_USER
+ value: "${DATABASE_USER}"
+ - name: POSTGRESQL_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: "${NAME}-secrets"
+ key: pg-password
+ - name: POSTGRESQL_DATABASE
+ value: "${DATABASE_NAME}"
+ - name: POSTGRESQL_MAX_CONNECTIONS
+ value: "${POSTGRESQL_MAX_CONNECTIONS}"
+ - name: POSTGRESQL_SHARED_BUFFERS
+ value: "${POSTGRESQL_SHARED_BUFFERS}"
+ - name: POSTGRESQL_CONFIG_DIR
+ value: "${POSTGRESQL_CONFIG_DIR}"
+ resources:
+ requests:
+ memory: "${POSTGRESQL_MEM_REQ}"
+ cpu: "${POSTGRESQL_CPU_REQ}"
+ limits:
+ memory: "${POSTGRESQL_MEM_LIMIT}"
+- apiVersion: v1
+ kind: Service
+ metadata:
+ annotations:
+ description: Exposes and load balances Ansible pods
+ service.alpha.openshift.io/dependencies: '[{"name":"${DATABASE_SERVICE_NAME}","namespace":"","kind":"Service"}]'
+ name: "${ANSIBLE_SERVICE_NAME}"
+ spec:
+ ports:
+ - name: http
+ port: 80
+ protocol: TCP
+ targetPort: 80
+ - name: https
+ port: 443
+ protocol: TCP
+ targetPort: 443
+ selector:
+ name: "${ANSIBLE_SERVICE_NAME}"
+- apiVersion: v1
+ kind: DeploymentConfig
+ metadata:
+ name: "${ANSIBLE_SERVICE_NAME}"
+ annotations:
+ description: Defines how to deploy the Ansible appliance
+ spec:
+ strategy:
+ type: Recreate
+ serviceName: "${ANSIBLE_SERVICE_NAME}"
+ replicas: 0
+ template:
+ metadata:
+ labels:
+ name: "${ANSIBLE_SERVICE_NAME}"
+ name: "${ANSIBLE_SERVICE_NAME}"
+ spec:
+ containers:
+ - name: ansible
+ image: "${ANSIBLE_IMG_NAME}:${ANSIBLE_IMG_TAG}"
+ livenessProbe:
+ tcpSocket:
+ port: 443
+ initialDelaySeconds: 480
+ timeoutSeconds: 3
+ readinessProbe:
+ httpGet:
+ path: "/"
+ port: 443
+ scheme: HTTPS
+ initialDelaySeconds: 200
+ timeoutSeconds: 3
+ ports:
+ - containerPort: 80
+ protocol: TCP
+ - containerPort: 443
+ protocol: TCP
+ securityContext:
+ privileged: true
+ env:
+ - name: ADMIN_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: "${ANSIBLE_SERVICE_NAME}-secrets"
+ key: admin-password
+ - name: RABBITMQ_USER_NAME
+ value: "${ANSIBLE_RABBITMQ_USER_NAME}"
+ - name: RABBITMQ_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: "${ANSIBLE_SERVICE_NAME}-secrets"
+ key: rabbit-password
+ - name: ANSIBLE_SECRET_KEY
+ valueFrom:
+ secretKeyRef:
+ name: "${ANSIBLE_SERVICE_NAME}-secrets"
+ key: secret-key
+ - name: DATABASE_SERVICE_NAME
+ value: "${DATABASE_SERVICE_NAME}"
+ - name: POSTGRESQL_USER
+ value: "${DATABASE_USER}"
+ - name: POSTGRESQL_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: "${NAME}-secrets"
+ key: pg-password
+ - name: POSTGRESQL_DATABASE
+ value: "${ANSIBLE_DATABASE_NAME}"
+ resources:
+ requests:
+ memory: "${ANSIBLE_MEM_REQ}"
+ cpu: "${ANSIBLE_CPU_REQ}"
+ limits:
+ memory: "${ANSIBLE_MEM_LIMIT}"
+ serviceAccount: cfme-privileged
+ serviceAccountName: cfme-privileged
+- apiVersion: v1
+ kind: Service
+ metadata:
+ name: "${HTTPD_SERVICE_NAME}"
+ annotations:
+ description: Exposes the httpd server
+ service.alpha.openshift.io/dependencies: '[{"name":"${NAME}","namespace":"","kind":"Service"}]'
+ spec:
+ ports:
+ - name: http
+ port: 80
+ targetPort: 80
+ selector:
+ name: httpd
+- apiVersion: v1
+ kind: Service
+ metadata:
+ name: "${HTTPD_DBUS_API_SERVICE_NAME}"
+ annotations:
+ description: Exposes the httpd server dbus api
+ service.alpha.openshift.io/dependencies: '[{"name":"${NAME}","namespace":"","kind":"Service"}]'
+ spec:
+ ports:
+ - name: http-dbus-api
+ port: 8080
+ targetPort: 8080
+ selector:
+ name: httpd
+- apiVersion: v1
+ kind: DeploymentConfig
+ metadata:
+ name: "${HTTPD_SERVICE_NAME}"
+ annotations:
+ description: Defines how to deploy httpd
+ spec:
+ strategy:
+ type: Recreate
+ recreateParams:
+ timeoutSeconds: 1200
+ triggers:
+ - type: ConfigChange
+ replicas: 1
+ selector:
+ name: "${HTTPD_SERVICE_NAME}"
+ template:
+ metadata:
+ name: "${HTTPD_SERVICE_NAME}"
+ labels:
+ name: "${HTTPD_SERVICE_NAME}"
+ spec:
+ volumes:
+ - name: httpd-config
+ configMap:
+ name: "${HTTPD_SERVICE_NAME}-configs"
+ - name: httpd-auth-config
+ configMap:
+ name: "${HTTPD_SERVICE_NAME}-auth-configs"
+ containers:
+ - name: httpd
+ image: "${HTTPD_IMG_NAME}:${HTTPD_IMG_TAG}"
+ ports:
+ - containerPort: 80
+ protocol: TCP
+ - containerPort: 8080
+ protocol: TCP
+ livenessProbe:
+ exec:
+ command:
+ - pidof
+ - httpd
+ initialDelaySeconds: 15
+ timeoutSeconds: 3
+ readinessProbe:
+ tcpSocket:
+ port: 80
+ initialDelaySeconds: 10
+ timeoutSeconds: 3
+ volumeMounts:
+ - name: httpd-config
+ mountPath: "${HTTPD_CONFIG_DIR}"
+ - name: httpd-auth-config
+ mountPath: "${HTTPD_AUTH_CONFIG_DIR}"
+ resources:
+ requests:
+ memory: "${HTTPD_MEM_REQ}"
+ cpu: "${HTTPD_CPU_REQ}"
+ limits:
+ memory: "${HTTPD_MEM_LIMIT}"
+ env:
+ - name: HTTPD_AUTH_TYPE
+ valueFrom:
+ configMapKeyRef:
+ name: "${HTTPD_SERVICE_NAME}-auth-configs"
+ key: auth-type
+ - name: HTTPD_AUTH_KERBEROS_REALMS
+ valueFrom:
+ configMapKeyRef:
+ name: "${HTTPD_SERVICE_NAME}-auth-configs"
+ key: auth-kerberos-realms
+ lifecycle:
+ postStart:
exec:
command:
- - "/bin/sh"
- - "-i"
- - "-c"
- - "psql -h 127.0.0.1 -U ${POSTGRESQL_USER} -q -d ${POSTGRESQL_DATABASE} -c 'SELECT 1'"
- livenessProbe:
- timeoutSeconds: 1
- initialDelaySeconds: 60
- tcpSocket:
- port: 5432
- volumeMounts:
- -
- name: "cfme-pgdb-volume"
- mountPath: "/var/lib/pgsql/data"
- env:
- -
- name: "POSTGRESQL_USER"
- value: "${DATABASE_USER}"
- -
- name: "POSTGRESQL_PASSWORD"
- value: "${DATABASE_PASSWORD}"
- -
- name: "POSTGRESQL_DATABASE"
- value: "${DATABASE_NAME}"
- -
- name: "POSTGRESQL_MAX_CONNECTIONS"
- value: "${POSTGRESQL_MAX_CONNECTIONS}"
- -
- name: "POSTGRESQL_SHARED_BUFFERS"
- value: "${POSTGRESQL_SHARED_BUFFERS}"
- resources:
- requests:
- memory: "${POSTGRESQL_MEM_REQ}"
- cpu: "${POSTGRESQL_CPU_REQ}"
- limits:
- memory: "${POSTGRESQL_MEM_LIMIT}"
-
+ - "/usr/bin/save-container-environment"
+ serviceAccount: cfme-httpd
+ serviceAccountName: cfme-httpd
parameters:
- -
- name: "NAME"
- displayName: Name
- required: true
- description: "The name assigned to all of the frontend objects defined in this template."
- value: cloudforms
- -
- name: "DATABASE_SERVICE_NAME"
- displayName: "PostgreSQL Service Name"
- required: true
- description: "The name of the OpenShift Service exposed for the PostgreSQL container."
- value: "postgresql"
- -
- name: "DATABASE_USER"
- displayName: "PostgreSQL User"
- required: true
- description: "PostgreSQL user that will access the database."
- value: "root"
- -
- name: "DATABASE_PASSWORD"
- displayName: "PostgreSQL Password"
- required: true
- description: "Password for the PostgreSQL user."
- value: "smartvm"
- -
- name: "DATABASE_NAME"
- required: true
- displayName: "PostgreSQL Database Name"
- description: "Name of the PostgreSQL database accessed."
- value: "vmdb_production"
- -
- name: "DATABASE_REGION"
- required: true
- displayName: "Application Database Region"
- description: "Database region that will be used for application."
- value: "0"
- -
- name: "MEMCACHED_SERVICE_NAME"
- required: true
- displayName: "Memcached Service Name"
- description: "The name of the OpenShift Service exposed for the Memcached container."
- value: "memcached"
- -
- name: "MEMCACHED_MAX_MEMORY"
- displayName: "Memcached Max Memory"
- description: "Memcached maximum memory for memcached object storage in MB."
- value: "64"
- -
- name: "MEMCACHED_MAX_CONNECTIONS"
- displayName: "Memcached Max Connections"
- description: "Memcached maximum number of connections allowed."
- value: "1024"
- -
- name: "MEMCACHED_SLAB_PAGE_SIZE"
- displayName: "Memcached Slab Page Size"
- description: "Memcached size of each slab page."
- value: "1m"
- -
- name: "POSTGRESQL_MAX_CONNECTIONS"
- displayName: "PostgreSQL Max Connections"
- description: "PostgreSQL maximum number of database connections allowed."
- value: "100"
- -
- name: "POSTGRESQL_SHARED_BUFFERS"
- displayName: "PostgreSQL Shared Buffer Amount"
- description: "Amount of memory dedicated for PostgreSQL shared memory buffers."
- value: "256MB"
- -
- name: "APPLICATION_CPU_REQ"
- displayName: "Application Min CPU Requested"
- required: true
- description: "Minimum amount of CPU time the Application container will need (expressed in millicores)."
- value: "1000m"
- -
- name: "POSTGRESQL_CPU_REQ"
- displayName: "PostgreSQL Min CPU Requested"
- required: true
- description: "Minimum amount of CPU time the PostgreSQL container will need (expressed in millicores)."
- value: "500m"
- -
- name: "MEMCACHED_CPU_REQ"
- displayName: "Memcached Min CPU Requested"
- required: true
- description: "Minimum amount of CPU time the Memcached container will need (expressed in millicores)."
- value: "200m"
- -
- name: "APPLICATION_MEM_REQ"
- displayName: "Application Min RAM Requested"
- required: true
- description: "Minimum amount of memory the Application container will need."
- value: "6144Mi"
- -
- name: "POSTGRESQL_MEM_REQ"
- displayName: "PostgreSQL Min RAM Requested"
- required: true
- description: "Minimum amount of memory the PostgreSQL container will need."
- value: "1024Mi"
- -
- name: "MEMCACHED_MEM_REQ"
- displayName: "Memcached Min RAM Requested"
- required: true
- description: "Minimum amount of memory the Memcached container will need."
- value: "64Mi"
- -
- name: "APPLICATION_MEM_LIMIT"
- displayName: "Application Max RAM Limit"
- required: true
- description: "Maximum amount of memory the Application container can consume."
- value: "16384Mi"
- -
- name: "POSTGRESQL_MEM_LIMIT"
- displayName: "PostgreSQL Max RAM Limit"
- required: true
- description: "Maximum amount of memory the PostgreSQL container can consume."
- value: "8192Mi"
- -
- name: "MEMCACHED_MEM_LIMIT"
- displayName: "Memcached Max RAM Limit"
- required: true
- description: "Maximum amount of memory the Memcached container can consume."
- value: "256Mi"
- -
- name: "POSTGRESQL_IMG_NAME"
- displayName: "PostgreSQL Image Name"
- description: "This is the PostgreSQL image name requested to deploy."
- value: "registry.access.redhat.com/cloudforms45/cfme-openshift-postgresql"
- -
- name: "POSTGRESQL_IMG_TAG"
- displayName: "PostgreSQL Image Tag"
- description: "This is the PostgreSQL image tag/version requested to deploy."
- value: "latest"
- -
- name: "MEMCACHED_IMG_NAME"
- displayName: "Memcached Image Name"
- description: "This is the Memcached image name requested to deploy."
- value: "registry.access.redhat.com/cloudforms45/cfme-openshift-memcached"
- -
- name: "MEMCACHED_IMG_TAG"
- displayName: "Memcached Image Tag"
- description: "This is the Memcached image tag/version requested to deploy."
- value: "latest"
- -
- name: "APPLICATION_IMG_NAME"
- displayName: "Application Image Name"
- description: "This is the Application image name requested to deploy."
- value: "registry.access.redhat.com/cloudforms45/cfme-openshift-app"
- -
- name: "APPLICATION_IMG_TAG"
- displayName: "Application Image Tag"
- description: "This is the Application image tag/version requested to deploy."
- value: "latest"
- -
- name: "APPLICATION_DOMAIN"
- displayName: "Application Hostname"
- description: "The exposed hostname that will route to the application service, if left blank a value will be defaulted."
- value: ""
- -
- name: "APPLICATION_INIT_DELAY"
- displayName: "Application Init Delay"
- required: true
- description: "Delay in seconds before we attempt to initialize the application."
- value: "15"
- -
- name: "APPLICATION_VOLUME_CAPACITY"
- displayName: "Application Volume Capacity"
- required: true
- description: "Volume space available for application data."
- value: "5Gi"
- -
- name: "APPLICATION_REGION_VOLUME_CAPACITY"
- displayName: "Application Region Volume Capacity"
- required: true
- description: "Volume space available for region application data."
- value: "5Gi"
- -
- name: "DATABASE_VOLUME_CAPACITY"
- displayName: "Database Volume Capacity"
- required: true
- description: "Volume space available for database."
- value: "15Gi"
+- name: NAME
+ displayName: Name
+ required: true
+ description: The name assigned to all of the frontend objects defined in this template.
+ value: cloudforms
+- name: V2_KEY
+ displayName: CloudForms Encryption Key
+ required: true
+ description: Encryption Key for CloudForms Passwords
+ from: "[a-zA-Z0-9]{43}"
+ generate: expression
+- name: DATABASE_SERVICE_NAME
+ displayName: PostgreSQL Service Name
+ required: true
+ description: The name of the OpenShift Service exposed for the PostgreSQL container.
+ value: postgresql
+- name: DATABASE_USER
+ displayName: PostgreSQL User
+ required: true
+ description: PostgreSQL user that will access the database.
+ value: root
+- name: DATABASE_PASSWORD
+ displayName: PostgreSQL Password
+ required: true
+ description: Password for the PostgreSQL user.
+ from: "[a-zA-Z0-9]{8}"
+ generate: expression
+- name: DATABASE_NAME
+ required: true
+ displayName: PostgreSQL Database Name
+ description: Name of the PostgreSQL database accessed.
+ value: vmdb_production
+- name: DATABASE_REGION
+ required: true
+ displayName: Application Database Region
+ description: Database region that will be used for application.
+ value: '0'
+- name: APPLICATION_ADMIN_PASSWORD
+ displayName: Application Admin Password
+ required: true
+ description: Admin password that will be set on the application.
+ value: smartvm
+- name: ANSIBLE_DATABASE_NAME
+ displayName: Ansible PostgreSQL database name
+ required: true
+ description: The database to be used by the Ansible continer
+ value: awx
+- name: MEMCACHED_SERVICE_NAME
+ required: true
+ displayName: Memcached Service Name
+ description: The name of the OpenShift Service exposed for the Memcached container.
+ value: memcached
+- name: MEMCACHED_MAX_MEMORY
+ displayName: Memcached Max Memory
+ description: Memcached maximum memory for memcached object storage in MB.
+ value: '64'
+- name: MEMCACHED_MAX_CONNECTIONS
+ displayName: Memcached Max Connections
+ description: Memcached maximum number of connections allowed.
+ value: '1024'
+- name: MEMCACHED_SLAB_PAGE_SIZE
+ displayName: Memcached Slab Page Size
+ description: Memcached size of each slab page.
+ value: 1m
+- name: POSTGRESQL_CONFIG_DIR
+ displayName: PostgreSQL Configuration Overrides
+ description: Directory used to store PostgreSQL configuration overrides.
+ value: "/var/lib/pgsql/conf.d"
+- name: POSTGRESQL_MAX_CONNECTIONS
+ displayName: PostgreSQL Max Connections
+ description: PostgreSQL maximum number of database connections allowed.
+ value: '1000'
+- name: POSTGRESQL_SHARED_BUFFERS
+ displayName: PostgreSQL Shared Buffer Amount
+ description: Amount of memory dedicated for PostgreSQL shared memory buffers.
+ value: 1GB
+- name: ANSIBLE_SERVICE_NAME
+ displayName: Ansible Service Name
+ description: The name of the OpenShift Service exposed for the Ansible container.
+ value: ansible
+- name: ANSIBLE_ADMIN_PASSWORD
+ displayName: Ansible admin User password
+ required: true
+ description: The password for the Ansible container admin user
+ from: "[a-zA-Z0-9]{32}"
+ generate: expression
+- name: ANSIBLE_SECRET_KEY
+ displayName: Ansible Secret Key
+ required: true
+ description: Encryption key for the Ansible container
+ from: "[a-f0-9]{32}"
+ generate: expression
+- name: ANSIBLE_RABBITMQ_USER_NAME
+ displayName: RabbitMQ Username
+ required: true
+ description: Username for the Ansible RabbitMQ Server
+ value: ansible
+- name: ANSIBLE_RABBITMQ_PASSWORD
+ displayName: RabbitMQ Server Password
+ required: true
+ description: Password for the Ansible RabbitMQ Server
+ from: "[a-zA-Z0-9]{32}"
+ generate: expression
+- name: APPLICATION_CPU_REQ
+ displayName: Application Min CPU Requested
+ required: true
+ description: Minimum amount of CPU time the Application container will need (expressed in millicores).
+ value: 1000m
+- name: POSTGRESQL_CPU_REQ
+ displayName: PostgreSQL Min CPU Requested
+ required: true
+ description: Minimum amount of CPU time the PostgreSQL container will need (expressed in millicores).
+ value: 500m
+- name: MEMCACHED_CPU_REQ
+ displayName: Memcached Min CPU Requested
+ required: true
+ description: Minimum amount of CPU time the Memcached container will need (expressed in millicores).
+ value: 200m
+- name: ANSIBLE_CPU_REQ
+ displayName: Ansible Min CPU Requested
+ required: true
+ description: Minimum amount of CPU time the Ansible container will need (expressed in millicores).
+ value: 1000m
+- name: APPLICATION_MEM_REQ
+ displayName: Application Min RAM Requested
+ required: true
+ description: Minimum amount of memory the Application container will need.
+ value: 6144Mi
+- name: POSTGRESQL_MEM_REQ
+ displayName: PostgreSQL Min RAM Requested
+ required: true
+ description: Minimum amount of memory the PostgreSQL container will need.
+ value: 4Gi
+- name: MEMCACHED_MEM_REQ
+ displayName: Memcached Min RAM Requested
+ required: true
+ description: Minimum amount of memory the Memcached container will need.
+ value: 64Mi
+- name: ANSIBLE_MEM_REQ
+ displayName: Ansible Min RAM Requested
+ required: true
+ description: Minimum amount of memory the Ansible container will need.
+ value: 2048Mi
+- name: APPLICATION_MEM_LIMIT
+ displayName: Application Max RAM Limit
+ required: true
+ description: Maximum amount of memory the Application container can consume.
+ value: 16384Mi
+- name: POSTGRESQL_MEM_LIMIT
+ displayName: PostgreSQL Max RAM Limit
+ required: true
+ description: Maximum amount of memory the PostgreSQL container can consume.
+ value: 8Gi
+- name: MEMCACHED_MEM_LIMIT
+ displayName: Memcached Max RAM Limit
+ required: true
+ description: Maximum amount of memory the Memcached container can consume.
+ value: 256Mi
+- name: ANSIBLE_MEM_LIMIT
+ displayName: Ansible Max RAM Limit
+ required: true
+ description: Maximum amount of memory the Ansible container can consume.
+ value: 8096Mi
+- name: POSTGRESQL_IMG_NAME
+ displayName: PostgreSQL Image Name
+ description: This is the PostgreSQL image name requested to deploy.
+ value: registry.access.redhat.com/cloudforms46-beta/cfme-openshift-postgresql
+- name: POSTGRESQL_IMG_TAG
+ displayName: PostgreSQL Image Tag
+ description: This is the PostgreSQL image tag/version requested to deploy.
+ value: latest
+- name: MEMCACHED_IMG_NAME
+ displayName: Memcached Image Name
+ description: This is the Memcached image name requested to deploy.
+ value: registry.access.redhat.com/cloudforms46-beta/cfme-openshift-memcached
+- name: MEMCACHED_IMG_TAG
+ displayName: Memcached Image Tag
+ description: This is the Memcached image tag/version requested to deploy.
+ value: latest
+- name: FRONTEND_APPLICATION_IMG_NAME
+ displayName: Frontend Application Image Name
+ description: This is the Frontend Application image name requested to deploy.
+ value: registry.access.redhat.com/cloudforms46-beta/cfme-openshift-app-ui
+- name: BACKEND_APPLICATION_IMG_NAME
+ displayName: Backend Application Image Name
+ description: This is the Backend Application image name requested to deploy.
+ value: registry.access.redhat.com/cloudforms46-beta/cfme-openshift-app
+- name: FRONTEND_APPLICATION_IMG_TAG
+ displayName: Front end Application Image Tag
+ description: This is the CloudForms Frontend Application image tag/version requested to deploy.
+ value: latest
+- name: BACKEND_APPLICATION_IMG_TAG
+ displayName: Back end Application Image Tag
+ description: This is the CloudForms Backend Application image tag/version requested to deploy.
+ value: latest
+- name: ANSIBLE_IMG_NAME
+ displayName: Ansible Image Name
+ description: This is the Ansible image name requested to deploy.
+ value: registry.access.redhat.com/cloudforms46-beta/cfme-openshift-embedded-ansible
+- name: ANSIBLE_IMG_TAG
+ displayName: Ansible Image Tag
+ description: This is the Ansible image tag/version requested to deploy.
+ value: latest
+- name: APPLICATION_DOMAIN
+ displayName: Application Hostname
+ description: The exposed hostname that will route to the application service, if left blank a value will be defaulted.
+ value: ''
+- name: APPLICATION_REPLICA_COUNT
+ displayName: Application Replica Count
+ description: This is the number of Application replicas requested to deploy.
+ value: '1'
+- name: APPLICATION_INIT_DELAY
+ displayName: Application Init Delay
+ required: true
+ description: Delay in seconds before we attempt to initialize the application.
+ value: '15'
+- name: APPLICATION_VOLUME_CAPACITY
+ displayName: Application Volume Capacity
+ required: true
+ description: Volume space available for application data.
+ value: 5Gi
+- name: DATABASE_VOLUME_CAPACITY
+ displayName: Database Volume Capacity
+ required: true
+ description: Volume space available for database.
+ value: 15Gi
+- name: HTTPD_SERVICE_NAME
+ required: true
+ displayName: Apache httpd Service Name
+ description: The name of the OpenShift Service exposed for the httpd container.
+ value: httpd
+- name: HTTPD_DBUS_API_SERVICE_NAME
+ required: true
+ displayName: Apache httpd DBus API Service Name
+ description: The name of httpd dbus api service.
+ value: httpd-dbus-api
+- name: HTTPD_IMG_NAME
+ displayName: Apache httpd Image Name
+ description: This is the httpd image name requested to deploy.
+ value: registry.access.redhat.com/cloudforms46-beta/cfme-openshift-httpd
+- name: HTTPD_IMG_TAG
+ displayName: Apache httpd Image Tag
+ description: This is the httpd image tag/version requested to deploy.
+ value: latest
+- name: HTTPD_CONFIG_DIR
+ displayName: Apache Configuration Directory
+ description: Directory used to store the Apache configuration files.
+ value: "/etc/httpd/conf.d"
+- name: HTTPD_AUTH_CONFIG_DIR
+ displayName: External Authentication Configuration Directory
+ description: Directory used to store the external authentication configuration files.
+ value: "/etc/httpd/auth-conf.d"
+- name: HTTPD_CPU_REQ
+ displayName: Apache httpd Min CPU Requested
+ required: true
+ description: Minimum amount of CPU time the httpd container will need (expressed in millicores).
+ value: 500m
+- name: HTTPD_MEM_REQ
+ displayName: Apache httpd Min RAM Requested
+ required: true
+ description: Minimum amount of memory the httpd container will need.
+ value: 512Mi
+- name: HTTPD_MEM_LIMIT
+ displayName: Apache httpd Max RAM Limit
+ required: true
+ description: Maximum amount of memory the httpd container can consume.
+ value: 8192Mi
diff --git a/roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-backup-job.yaml b/roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-backup-job.yaml
new file mode 100644
index 000000000..48d1d4e26
--- /dev/null
+++ b/roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-backup-job.yaml
@@ -0,0 +1,28 @@
+apiVersion: batch/v1
+kind: Job
+metadata:
+ name: cloudforms-backup
+spec:
+ template:
+ metadata:
+ name: cloudforms-backup
+ spec:
+ containers:
+ - name: postgresql
+ image: registry.access.redhat.com/cloudforms46-beta/cfme-openshift-postgresql:latest
+ command:
+ - "/opt/rh/cfme-container-scripts/backup_db"
+ env:
+ - name: DATABASE_URL
+ valueFrom:
+ secretKeyRef:
+ name: cloudforms-secrets
+ key: database-url
+ volumeMounts:
+ - name: cfme-backup-vol
+ mountPath: "/backups"
+ volumes:
+ - name: cfme-backup-vol
+ persistentVolumeClaim:
+ claimName: cloudforms-backup
+ restartPolicy: Never
diff --git a/roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-backup-pvc.yaml b/roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-backup-pvc.yaml
new file mode 100644
index 000000000..92598ce82
--- /dev/null
+++ b/roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-backup-pvc.yaml
@@ -0,0 +1,10 @@
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+ name: cloudforms-backup
+spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: 15Gi
diff --git a/roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-pv-backup-example.yaml b/roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-pv-backup-example.yaml
new file mode 100644
index 000000000..4fe349897
--- /dev/null
+++ b/roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-pv-backup-example.yaml
@@ -0,0 +1,13 @@
+apiVersion: v1
+kind: PersistentVolume
+metadata:
+ name: cfme-pv03
+spec:
+ capacity:
+ storage: 15Gi
+ accessModes:
+ - ReadWriteOnce
+ nfs:
+ path: "/exports/cfme-pv03"
+ server: "<your-nfs-host-here>"
+ persistentVolumeReclaimPolicy: Retain
diff --git a/roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-pv-db-example.yaml b/roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-pv-db-example.yaml
index 250a99b8d..0cdd821b5 100644
--- a/roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-pv-db-example.yaml
+++ b/roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-pv-db-example.yaml
@@ -1,13 +1,38 @@
apiVersion: v1
-kind: PersistentVolume
+kind: Template
+labels:
+ template: cloudforms-db-pv
metadata:
- name: cfme-pv01
-spec:
- capacity:
- storage: 15Gi
- accessModes:
+ name: cloudforms-db-pv
+ annotations:
+ description: PV Template for CFME PostgreSQL DB
+ tags: PVS, CFME
+objects:
+- apiVersion: v1
+ kind: PersistentVolume
+ metadata:
+ name: cfme-db
+ spec:
+ capacity:
+ storage: "${PV_SIZE}"
+ accessModes:
- ReadWriteOnce
- nfs:
- path: /exports/cfme-pv01
- server: <your-nfs-host-here>
- persistentVolumeReclaimPolicy: Retain
+ nfs:
+ path: "${BASE_PATH}/cfme-db"
+ server: "${NFS_HOST}"
+ persistentVolumeReclaimPolicy: Retain
+parameters:
+- name: PV_SIZE
+ displayName: PV Size for DB
+ required: true
+ description: The size of the CFME DB PV given in Gi
+ value: 15Gi
+- name: BASE_PATH
+ displayName: Exports Directory Base Path
+ required: true
+ description: The parent directory of your NFS exports
+ value: "/exports"
+- name: NFS_HOST
+ displayName: NFS Server Hostname
+ required: true
+ description: The hostname or IP address of the NFS server
diff --git a/roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-pv-region-example.yaml b/roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-pv-region-example.yaml
deleted file mode 100644
index cba9bbe35..000000000
--- a/roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-pv-region-example.yaml
+++ /dev/null
@@ -1,13 +0,0 @@
-apiVersion: v1
-kind: PersistentVolume
-metadata:
- name: cfme-pv02
-spec:
- capacity:
- storage: 5Gi
- accessModes:
- - ReadWriteOnce
- nfs:
- path: /exports/cfme-pv02
- server: <your-nfs-host-here>
- persistentVolumeReclaimPolicy: Retain
diff --git a/roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-pv-server-example.yaml b/roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-pv-server-example.yaml
index c08c21265..527090ae8 100644
--- a/roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-pv-server-example.yaml
+++ b/roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-pv-server-example.yaml
@@ -1,13 +1,38 @@
apiVersion: v1
-kind: PersistentVolume
+kind: Template
+labels:
+ template: cloudforms-app-pv
metadata:
- name: cfme-pv03
-spec:
- capacity:
- storage: 5Gi
- accessModes:
+ name: cloudforms-app-pv
+ annotations:
+ description: PV Template for CFME Server
+ tags: PVS, CFME
+objects:
+- apiVersion: v1
+ kind: PersistentVolume
+ metadata:
+ name: cfme-app
+ spec:
+ capacity:
+ storage: "${PV_SIZE}"
+ accessModes:
- ReadWriteOnce
- nfs:
- path: /exports/cfme-pv03
- server: <your-nfs-host-here>
- persistentVolumeReclaimPolicy: Retain
+ nfs:
+ path: "${BASE_PATH}/cfme-app"
+ server: "${NFS_HOST}"
+ persistentVolumeReclaimPolicy: Retain
+parameters:
+- name: PV_SIZE
+ displayName: PV Size for App
+ required: true
+ description: The size of the CFME APP PV given in Gi
+ value: 5Gi
+- name: BASE_PATH
+ displayName: Exports Directory Base Path
+ required: true
+ description: The parent directory of your NFS exports
+ value: "/exports"
+- name: NFS_HOST
+ displayName: NFS Server Hostname
+ required: true
+ description: The hostname or IP address of the NFS server
diff --git a/roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-restore-job.yaml b/roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-restore-job.yaml
new file mode 100644
index 000000000..7fd4fc2e1
--- /dev/null
+++ b/roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-restore-job.yaml
@@ -0,0 +1,35 @@
+apiVersion: batch/v1
+kind: Job
+metadata:
+ name: cloudforms-restore
+spec:
+ template:
+ metadata:
+ name: cloudforms-restore
+ spec:
+ containers:
+ - name: postgresql
+ image: registry.access.redhat.com/cloudforms46-beta/cfme-openshift-postgresql:latest
+ command:
+ - "/opt/rh/cfme-container-scripts/restore_db"
+ env:
+ - name: DATABASE_URL
+ valueFrom:
+ secretKeyRef:
+ name: cloudforms-secrets
+ key: database-url
+ - name: BACKUP_VERSION
+ value: latest
+ volumeMounts:
+ - name: cfme-backup-vol
+ mountPath: "/backups"
+ - name: cfme-prod-vol
+ mountPath: "/restore"
+ volumes:
+ - name: cfme-backup-vol
+ persistentVolumeClaim:
+ claimName: cloudforms-backup
+ - name: cfme-prod-vol
+ persistentVolumeClaim:
+ claimName: cloudforms-postgresql
+ restartPolicy: Never
diff --git a/roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-scc-sysadmin.yaml b/roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-scc-sysadmin.yaml
new file mode 100644
index 000000000..d2ece9298
--- /dev/null
+++ b/roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-scc-sysadmin.yaml
@@ -0,0 +1,38 @@
+allowHostDirVolumePlugin: false
+allowHostIPC: false
+allowHostNetwork: false
+allowHostPID: false
+allowHostPorts: false
+allowPrivilegedContainer: false
+allowedCapabilities:
+apiVersion: v1
+defaultAddCapabilities:
+- SYS_ADMIN
+fsGroup:
+ type: RunAsAny
+groups:
+- system:cluster-admins
+kind: SecurityContextConstraints
+metadata:
+ annotations:
+ kubernetes.io/description: cfme-sysadmin provides all features of the anyuid SCC but allows users to have SYS_ADMIN capabilities. This is the required scc for Pods requiring to run with systemd and the message bus.
+ creationTimestamp:
+ name: cfme-sysadmin
+priority: 10
+readOnlyRootFilesystem: false
+requiredDropCapabilities:
+- MKNOD
+- SYS_CHROOT
+runAsUser:
+ type: RunAsAny
+seLinuxContext:
+ type: MustRunAs
+supplementalGroups:
+ type: RunAsAny
+users:
+volumes:
+- configMap
+- downwardAPI
+- emptyDir
+- persistentVolumeClaim
+- secret
diff --git a/roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-template-ext-db.yaml b/roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-template-ext-db.yaml
new file mode 100644
index 000000000..9866c29c3
--- /dev/null
+++ b/roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-template-ext-db.yaml
@@ -0,0 +1,956 @@
+apiVersion: v1
+kind: Template
+labels:
+ template: cloudforms-ext-db
+metadata:
+ name: cloudforms-ext-db
+ annotations:
+ description: CloudForms appliance with persistent storage using a external DB host
+ tags: instant-app,cloudforms,cfme
+ iconClass: icon-rails
+objects:
+- apiVersion: v1
+ kind: ServiceAccount
+ metadata:
+ name: cfme-orchestrator
+- apiVersion: v1
+ kind: ServiceAccount
+ metadata:
+ name: cfme-anyuid
+- apiVersion: v1
+ kind: ServiceAccount
+ metadata:
+ name: cfme-privileged
+- apiVersion: v1
+ kind: ServiceAccount
+ metadata:
+ name: cfme-httpd
+- apiVersion: v1
+ kind: Secret
+ metadata:
+ name: "${NAME}-secrets"
+ stringData:
+ pg-password: "${DATABASE_PASSWORD}"
+ admin-password: "${APPLICATION_ADMIN_PASSWORD}"
+ database-url: postgresql://${DATABASE_USER}:${DATABASE_PASSWORD}@${DATABASE_SERVICE_NAME}/${DATABASE_NAME}?encoding=utf8&pool=5&wait_timeout=5
+ v2-key: "${V2_KEY}"
+- apiVersion: v1
+ kind: Secret
+ metadata:
+ name: "${ANSIBLE_SERVICE_NAME}-secrets"
+ stringData:
+ rabbit-password: "${ANSIBLE_RABBITMQ_PASSWORD}"
+ secret-key: "${ANSIBLE_SECRET_KEY}"
+ admin-password: "${ANSIBLE_ADMIN_PASSWORD}"
+- apiVersion: v1
+ kind: Service
+ metadata:
+ annotations:
+ description: Exposes and load balances CloudForms pods
+ service.alpha.openshift.io/dependencies: '[{"name":"${DATABASE_SERVICE_NAME}","namespace":"","kind":"Service"},{"name":"${MEMCACHED_SERVICE_NAME}","namespace":"","kind":"Service"}]'
+ name: "${NAME}"
+ spec:
+ clusterIP: None
+ ports:
+ - name: http
+ port: 80
+ protocol: TCP
+ targetPort: 80
+ selector:
+ name: "${NAME}"
+- apiVersion: v1
+ kind: Route
+ metadata:
+ name: "${HTTPD_SERVICE_NAME}"
+ spec:
+ host: "${APPLICATION_DOMAIN}"
+ port:
+ targetPort: http
+ tls:
+ termination: edge
+ insecureEdgeTerminationPolicy: Redirect
+ to:
+ kind: Service
+ name: "${HTTPD_SERVICE_NAME}"
+- apiVersion: apps/v1beta1
+ kind: StatefulSet
+ metadata:
+ name: "${NAME}"
+ annotations:
+ description: Defines how to deploy the CloudForms appliance
+ spec:
+ serviceName: "${NAME}"
+ replicas: "${APPLICATION_REPLICA_COUNT}"
+ template:
+ metadata:
+ labels:
+ name: "${NAME}"
+ name: "${NAME}"
+ spec:
+ containers:
+ - name: cloudforms
+ image: "${FRONTEND_APPLICATION_IMG_NAME}:${FRONTEND_APPLICATION_IMG_TAG}"
+ livenessProbe:
+ exec:
+ command:
+ - pidof
+ - MIQ Server
+ initialDelaySeconds: 480
+ timeoutSeconds: 3
+ readinessProbe:
+ tcpSocket:
+ port: 80
+ initialDelaySeconds: 200
+ timeoutSeconds: 3
+ ports:
+ - containerPort: 80
+ protocol: TCP
+ volumeMounts:
+ - name: "${NAME}-server"
+ mountPath: "/persistent"
+ env:
+ - name: MY_POD_NAMESPACE
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.namespace
+ - name: APPLICATION_INIT_DELAY
+ value: "${APPLICATION_INIT_DELAY}"
+ - name: DATABASE_REGION
+ value: "${DATABASE_REGION}"
+ - name: DATABASE_URL
+ valueFrom:
+ secretKeyRef:
+ name: "${NAME}-secrets"
+ key: database-url
+ - name: V2_KEY
+ valueFrom:
+ secretKeyRef:
+ name: "${NAME}-secrets"
+ key: v2-key
+ - name: APPLICATION_ADMIN_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: "${NAME}-secrets"
+ key: admin-password
+ - name: ANSIBLE_ADMIN_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: "${ANSIBLE_SERVICE_NAME}-secrets"
+ key: admin-password
+ resources:
+ requests:
+ memory: "${APPLICATION_MEM_REQ}"
+ cpu: "${APPLICATION_CPU_REQ}"
+ limits:
+ memory: "${APPLICATION_MEM_LIMIT}"
+ lifecycle:
+ preStop:
+ exec:
+ command:
+ - "/opt/rh/cfme-container-scripts/sync-pv-data"
+ serviceAccount: cfme-orchestrator
+ serviceAccountName: cfme-orchestrator
+ terminationGracePeriodSeconds: 90
+ volumeClaimTemplates:
+ - metadata:
+ name: "${NAME}-server"
+ annotations:
+ spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: "${APPLICATION_VOLUME_CAPACITY}"
+- apiVersion: v1
+ kind: Service
+ metadata:
+ annotations:
+ description: Headless service for CloudForms backend pods
+ name: "${NAME}-backend"
+ spec:
+ clusterIP: None
+ selector:
+ name: "${NAME}-backend"
+- apiVersion: apps/v1beta1
+ kind: StatefulSet
+ metadata:
+ name: "${NAME}-backend"
+ annotations:
+ description: Defines how to deploy the CloudForms appliance
+ spec:
+ serviceName: "${NAME}-backend"
+ replicas: 0
+ template:
+ metadata:
+ labels:
+ name: "${NAME}-backend"
+ name: "${NAME}-backend"
+ spec:
+ containers:
+ - name: cloudforms
+ image: "${BACKEND_APPLICATION_IMG_NAME}:${BACKEND_APPLICATION_IMG_TAG}"
+ livenessProbe:
+ exec:
+ command:
+ - pidof
+ - MIQ Server
+ initialDelaySeconds: 480
+ timeoutSeconds: 3
+ volumeMounts:
+ - name: "${NAME}-server"
+ mountPath: "/persistent"
+ env:
+ - name: APPLICATION_INIT_DELAY
+ value: "${APPLICATION_INIT_DELAY}"
+ - name: DATABASE_URL
+ valueFrom:
+ secretKeyRef:
+ name: "${NAME}-secrets"
+ key: database-url
+ - name: MIQ_SERVER_DEFAULT_ROLES
+ value: database_operations,event,reporting,scheduler,smartstate,ems_operations,ems_inventory,automate
+ - name: FRONTEND_SERVICE_NAME
+ value: "${NAME}"
+ - name: V2_KEY
+ valueFrom:
+ secretKeyRef:
+ name: "${NAME}-secrets"
+ key: v2-key
+ - name: ANSIBLE_ADMIN_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: "${ANSIBLE_SERVICE_NAME}-secrets"
+ key: admin-password
+ resources:
+ requests:
+ memory: "${APPLICATION_MEM_REQ}"
+ cpu: "${APPLICATION_CPU_REQ}"
+ limits:
+ memory: "${APPLICATION_MEM_LIMIT}"
+ lifecycle:
+ preStop:
+ exec:
+ command:
+ - "/opt/rh/cfme-container-scripts/sync-pv-data"
+ serviceAccount: cfme-orchestrator
+ serviceAccountName: cfme-orchestrator
+ terminationGracePeriodSeconds: 90
+ volumeClaimTemplates:
+ - metadata:
+ name: "${NAME}-server"
+ annotations:
+ spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: "${APPLICATION_VOLUME_CAPACITY}"
+- apiVersion: v1
+ kind: Service
+ metadata:
+ name: "${MEMCACHED_SERVICE_NAME}"
+ annotations:
+ description: Exposes the memcached server
+ spec:
+ ports:
+ - name: memcached
+ port: 11211
+ targetPort: 11211
+ selector:
+ name: "${MEMCACHED_SERVICE_NAME}"
+- apiVersion: v1
+ kind: DeploymentConfig
+ metadata:
+ name: "${MEMCACHED_SERVICE_NAME}"
+ annotations:
+ description: Defines how to deploy memcached
+ spec:
+ strategy:
+ type: Recreate
+ triggers:
+ - type: ConfigChange
+ replicas: 1
+ selector:
+ name: "${MEMCACHED_SERVICE_NAME}"
+ template:
+ metadata:
+ name: "${MEMCACHED_SERVICE_NAME}"
+ labels:
+ name: "${MEMCACHED_SERVICE_NAME}"
+ spec:
+ volumes: []
+ containers:
+ - name: memcached
+ image: "${MEMCACHED_IMG_NAME}:${MEMCACHED_IMG_TAG}"
+ ports:
+ - containerPort: 11211
+ readinessProbe:
+ timeoutSeconds: 1
+ initialDelaySeconds: 5
+ tcpSocket:
+ port: 11211
+ livenessProbe:
+ timeoutSeconds: 1
+ initialDelaySeconds: 30
+ tcpSocket:
+ port: 11211
+ volumeMounts: []
+ env:
+ - name: MEMCACHED_MAX_MEMORY
+ value: "${MEMCACHED_MAX_MEMORY}"
+ - name: MEMCACHED_MAX_CONNECTIONS
+ value: "${MEMCACHED_MAX_CONNECTIONS}"
+ - name: MEMCACHED_SLAB_PAGE_SIZE
+ value: "${MEMCACHED_SLAB_PAGE_SIZE}"
+ resources:
+ requests:
+ memory: "${MEMCACHED_MEM_REQ}"
+ cpu: "${MEMCACHED_CPU_REQ}"
+ limits:
+ memory: "${MEMCACHED_MEM_LIMIT}"
+- apiVersion: v1
+ kind: Service
+ metadata:
+ name: "${DATABASE_SERVICE_NAME}"
+ annotations:
+ description: Remote database service
+ spec:
+ ports:
+ - name: postgresql
+ port: 5432
+ targetPort: "${{DATABASE_PORT}}"
+ selector: {}
+- apiVersion: v1
+ kind: Endpoints
+ metadata:
+ name: "${DATABASE_SERVICE_NAME}"
+ subsets:
+ - addresses:
+ - ip: "${DATABASE_IP}"
+ ports:
+ - port: "${{DATABASE_PORT}}"
+ name: postgresql
+- apiVersion: v1
+ kind: Service
+ metadata:
+ annotations:
+ description: Exposes and load balances Ansible pods
+ service.alpha.openshift.io/dependencies: '[{"name":"${DATABASE_SERVICE_NAME}","namespace":"","kind":"Service"}]'
+ name: "${ANSIBLE_SERVICE_NAME}"
+ spec:
+ ports:
+ - name: http
+ port: 80
+ protocol: TCP
+ targetPort: 80
+ - name: https
+ port: 443
+ protocol: TCP
+ targetPort: 443
+ selector:
+ name: "${ANSIBLE_SERVICE_NAME}"
+- apiVersion: v1
+ kind: DeploymentConfig
+ metadata:
+ name: "${ANSIBLE_SERVICE_NAME}"
+ annotations:
+ description: Defines how to deploy the Ansible appliance
+ spec:
+ strategy:
+ type: Recreate
+ serviceName: "${ANSIBLE_SERVICE_NAME}"
+ replicas: 0
+ template:
+ metadata:
+ labels:
+ name: "${ANSIBLE_SERVICE_NAME}"
+ name: "${ANSIBLE_SERVICE_NAME}"
+ spec:
+ containers:
+ - name: ansible
+ image: "${ANSIBLE_IMG_NAME}:${ANSIBLE_IMG_TAG}"
+ livenessProbe:
+ tcpSocket:
+ port: 443
+ initialDelaySeconds: 480
+ timeoutSeconds: 3
+ readinessProbe:
+ httpGet:
+ path: "/"
+ port: 443
+ scheme: HTTPS
+ initialDelaySeconds: 200
+ timeoutSeconds: 3
+ ports:
+ - containerPort: 80
+ protocol: TCP
+ - containerPort: 443
+ protocol: TCP
+ securityContext:
+ privileged: true
+ env:
+ - name: ADMIN_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: "${ANSIBLE_SERVICE_NAME}-secrets"
+ key: admin-password
+ - name: RABBITMQ_USER_NAME
+ value: "${ANSIBLE_RABBITMQ_USER_NAME}"
+ - name: RABBITMQ_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: "${ANSIBLE_SERVICE_NAME}-secrets"
+ key: rabbit-password
+ - name: ANSIBLE_SECRET_KEY
+ valueFrom:
+ secretKeyRef:
+ name: "${ANSIBLE_SERVICE_NAME}-secrets"
+ key: secret-key
+ - name: DATABASE_SERVICE_NAME
+ value: "${DATABASE_SERVICE_NAME}"
+ - name: POSTGRESQL_USER
+ value: "${DATABASE_USER}"
+ - name: POSTGRESQL_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: "${NAME}-secrets"
+ key: pg-password
+ - name: POSTGRESQL_DATABASE
+ value: "${ANSIBLE_DATABASE_NAME}"
+ resources:
+ requests:
+ memory: "${ANSIBLE_MEM_REQ}"
+ cpu: "${ANSIBLE_CPU_REQ}"
+ limits:
+ memory: "${ANSIBLE_MEM_LIMIT}"
+ serviceAccount: cfme-privileged
+ serviceAccountName: cfme-privileged
+- apiVersion: v1
+ kind: ConfigMap
+ metadata:
+ name: "${HTTPD_SERVICE_NAME}-configs"
+ data:
+ application.conf: |
+ # Timeout: The number of seconds before receives and sends time out.
+ Timeout 120
+
+ RewriteEngine On
+ Options SymLinksIfOwnerMatch
+
+ <VirtualHost *:80>
+ KeepAlive on
+ # Without ServerName mod_auth_mellon compares against http:// and not https:// from the IdP
+ ServerName https://%{REQUEST_HOST}
+
+ ProxyPreserveHost on
+
+ RewriteCond %{REQUEST_URI} ^/ws [NC]
+ RewriteCond %{HTTP:UPGRADE} ^websocket$ [NC]
+ RewriteCond %{HTTP:CONNECTION} ^Upgrade$ [NC]
+ RewriteRule .* ws://${NAME}%{REQUEST_URI} [P,QSA,L]
+
+ # For httpd, some ErrorDocuments must by served by the httpd pod
+ RewriteCond %{REQUEST_URI} !^/proxy_pages
+
+ # For SAML /saml2 is only served by mod_auth_mellon in the httpd pod
+ RewriteCond %{REQUEST_URI} !^/saml2
+ RewriteRule ^/ http://${NAME}%{REQUEST_URI} [P,QSA,L]
+ ProxyPassReverse / http://${NAME}/
+
+ # Ensures httpd stdout/stderr are seen by docker logs.
+ ErrorLog "| /usr/bin/tee /proc/1/fd/2 /var/log/httpd/error_log"
+ CustomLog "| /usr/bin/tee /proc/1/fd/1 /var/log/httpd/access_log" common
+ </VirtualHost>
+ authentication.conf: |
+ # Load appropriate authentication configuration files
+ #
+ Include "conf.d/configuration-${HTTPD_AUTH_TYPE}-auth"
+ configuration-internal-auth: |
+ # Internal authentication
+ #
+ configuration-external-auth: |
+ Include "conf.d/external-auth-load-modules-conf"
+
+ <Location /dashboard/kerberos_authenticate>
+ AuthType Kerberos
+ AuthName "Kerberos Login"
+ KrbMethodNegotiate On
+ KrbMethodK5Passwd Off
+ KrbAuthRealms ${HTTPD_AUTH_KERBEROS_REALMS}
+ Krb5KeyTab /etc/http.keytab
+ KrbServiceName Any
+ Require pam-account httpd-auth
+
+ ErrorDocument 401 /proxy_pages/invalid_sso_credentials.js
+ </Location>
+
+ Include "conf.d/external-auth-login-form-conf"
+ Include "conf.d/external-auth-application-api-conf"
+ Include "conf.d/external-auth-lookup-user-details-conf"
+ Include "conf.d/external-auth-remote-user-conf"
+ configuration-active-directory-auth: |
+ Include "conf.d/external-auth-load-modules-conf"
+
+ <Location /dashboard/kerberos_authenticate>
+ AuthType Kerberos
+ AuthName "Kerberos Login"
+ KrbMethodNegotiate On
+ KrbMethodK5Passwd Off
+ KrbAuthRealms ${HTTPD_AUTH_KERBEROS_REALMS}
+ Krb5KeyTab /etc/krb5.keytab
+ KrbServiceName Any
+ Require pam-account httpd-auth
+
+ ErrorDocument 401 /proxy_pages/invalid_sso_credentials.js
+ </Location>
+
+ Include "conf.d/external-auth-login-form-conf"
+ Include "conf.d/external-auth-application-api-conf"
+ Include "conf.d/external-auth-lookup-user-details-conf"
+ Include "conf.d/external-auth-remote-user-conf"
+ configuration-saml-auth: |
+ LoadModule auth_mellon_module modules/mod_auth_mellon.so
+
+ <Location />
+ MellonEnable "info"
+
+ MellonIdPMetadataFile "/etc/httpd/saml2/idp-metadata.xml"
+
+ MellonSPPrivateKeyFile "/etc/httpd/saml2/sp-key.key"
+ MellonSPCertFile "/etc/httpd/saml2/sp-cert.cert"
+ MellonSPMetadataFile "/etc/httpd/saml2/sp-metadata.xml"
+
+ MellonVariable "sp-cookie"
+ MellonSecureCookie On
+ MellonCookiePath "/"
+
+ MellonIdP "IDP"
+
+ MellonEndpointPath "/saml2"
+
+ MellonUser username
+ MellonMergeEnvVars On
+
+ MellonSetEnvNoPrefix "REMOTE_USER" username
+ MellonSetEnvNoPrefix "REMOTE_USER_EMAIL" email
+ MellonSetEnvNoPrefix "REMOTE_USER_FIRSTNAME" firstname
+ MellonSetEnvNoPrefix "REMOTE_USER_LASTNAME" lastname
+ MellonSetEnvNoPrefix "REMOTE_USER_FULLNAME" fullname
+ MellonSetEnvNoPrefix "REMOTE_USER_GROUPS" groups
+ </Location>
+
+ <Location /saml_login>
+ AuthType "Mellon"
+ MellonEnable "auth"
+ Require valid-user
+ </Location>
+
+ Include "conf.d/external-auth-remote-user-conf"
+ external-auth-load-modules-conf: |
+ LoadModule authnz_pam_module modules/mod_authnz_pam.so
+ LoadModule intercept_form_submit_module modules/mod_intercept_form_submit.so
+ LoadModule lookup_identity_module modules/mod_lookup_identity.so
+ LoadModule auth_kerb_module modules/mod_auth_kerb.so
+ external-auth-login-form-conf: |
+ <Location /dashboard/external_authenticate>
+ InterceptFormPAMService httpd-auth
+ InterceptFormLogin user_name
+ InterceptFormPassword user_password
+ InterceptFormLoginSkip admin
+ InterceptFormClearRemoteUserForSkipped on
+ </Location>
+ external-auth-application-api-conf: |
+ <LocationMatch ^/api>
+ SetEnvIf Authorization '^Basic +YWRtaW46' let_admin_in
+ SetEnvIf X-Auth-Token '^.+$' let_api_token_in
+ SetEnvIf X-MIQ-Token '^.+$' let_sys_token_in
+
+ AuthType Basic
+ AuthName "External Authentication (httpd) for API"
+ AuthBasicProvider PAM
+
+ AuthPAMService httpd-auth
+ Require valid-user
+ Order Allow,Deny
+ Allow from env=let_admin_in
+ Allow from env=let_api_token_in
+ Allow from env=let_sys_token_in
+ Satisfy Any
+ </LocationMatch>
+ external-auth-lookup-user-details-conf: |
+ <LocationMatch ^/dashboard/external_authenticate$|^/dashboard/kerberos_authenticate$|^/api>
+ LookupUserAttr mail REMOTE_USER_EMAIL
+ LookupUserAttr givenname REMOTE_USER_FIRSTNAME
+ LookupUserAttr sn REMOTE_USER_LASTNAME
+ LookupUserAttr displayname REMOTE_USER_FULLNAME
+ LookupUserAttr domainname REMOTE_USER_DOMAIN
+
+ LookupUserGroups REMOTE_USER_GROUPS ":"
+ LookupDbusTimeout 5000
+ </LocationMatch>
+ external-auth-remote-user-conf: |
+ RequestHeader unset X_REMOTE_USER
+
+ RequestHeader set X_REMOTE_USER %{REMOTE_USER}e env=REMOTE_USER
+ RequestHeader set X_EXTERNAL_AUTH_ERROR %{EXTERNAL_AUTH_ERROR}e env=EXTERNAL_AUTH_ERROR
+ RequestHeader set X_REMOTE_USER_EMAIL %{REMOTE_USER_EMAIL}e env=REMOTE_USER_EMAIL
+ RequestHeader set X_REMOTE_USER_FIRSTNAME %{REMOTE_USER_FIRSTNAME}e env=REMOTE_USER_FIRSTNAME
+ RequestHeader set X_REMOTE_USER_LASTNAME %{REMOTE_USER_LASTNAME}e env=REMOTE_USER_LASTNAME
+ RequestHeader set X_REMOTE_USER_FULLNAME %{REMOTE_USER_FULLNAME}e env=REMOTE_USER_FULLNAME
+ RequestHeader set X_REMOTE_USER_GROUPS %{REMOTE_USER_GROUPS}e env=REMOTE_USER_GROUPS
+ RequestHeader set X_REMOTE_USER_DOMAIN %{REMOTE_USER_DOMAIN}e env=REMOTE_USER_DOMAIN
+- apiVersion: v1
+ kind: ConfigMap
+ metadata:
+ name: "${HTTPD_SERVICE_NAME}-auth-configs"
+ data:
+ auth-type: internal
+ auth-kerberos-realms: undefined
+ auth-configuration.conf: |
+ # External Authentication Configuration File
+ #
+ # For details on usage please see https://github.com/ManageIQ/manageiq-pods/blob/master/README.md#configuring-external-authentication
+- apiVersion: v1
+ kind: Service
+ metadata:
+ name: "${HTTPD_SERVICE_NAME}"
+ annotations:
+ description: Exposes the httpd server
+ service.alpha.openshift.io/dependencies: '[{"name":"${NAME}","namespace":"","kind":"Service"}]'
+ spec:
+ ports:
+ - name: http
+ port: 80
+ targetPort: 80
+ selector:
+ name: httpd
+- apiVersion: v1
+ kind: Service
+ metadata:
+ name: "${HTTPD_DBUS_API_SERVICE_NAME}"
+ annotations:
+ description: Exposes the httpd server dbus api
+ service.alpha.openshift.io/dependencies: '[{"name":"${NAME}","namespace":"","kind":"Service"}]'
+ spec:
+ ports:
+ - name: http-dbus-api
+ port: 8080
+ targetPort: 8080
+ selector:
+ name: httpd
+- apiVersion: v1
+ kind: DeploymentConfig
+ metadata:
+ name: "${HTTPD_SERVICE_NAME}"
+ annotations:
+ description: Defines how to deploy httpd
+ spec:
+ strategy:
+ type: Recreate
+ recreateParams:
+ timeoutSeconds: 1200
+ triggers:
+ - type: ConfigChange
+ replicas: 1
+ selector:
+ name: "${HTTPD_SERVICE_NAME}"
+ template:
+ metadata:
+ name: "${HTTPD_SERVICE_NAME}"
+ labels:
+ name: "${HTTPD_SERVICE_NAME}"
+ spec:
+ volumes:
+ - name: httpd-config
+ configMap:
+ name: "${HTTPD_SERVICE_NAME}-configs"
+ - name: httpd-auth-config
+ configMap:
+ name: "${HTTPD_SERVICE_NAME}-auth-configs"
+ containers:
+ - name: httpd
+ image: "${HTTPD_IMG_NAME}:${HTTPD_IMG_TAG}"
+ ports:
+ - containerPort: 80
+ protocol: TCP
+ - containerPort: 8080
+ protocol: TCP
+ livenessProbe:
+ exec:
+ command:
+ - pidof
+ - httpd
+ initialDelaySeconds: 15
+ timeoutSeconds: 3
+ readinessProbe:
+ tcpSocket:
+ port: 80
+ initialDelaySeconds: 10
+ timeoutSeconds: 3
+ volumeMounts:
+ - name: httpd-config
+ mountPath: "${HTTPD_CONFIG_DIR}"
+ - name: httpd-auth-config
+ mountPath: "${HTTPD_AUTH_CONFIG_DIR}"
+ resources:
+ requests:
+ memory: "${HTTPD_MEM_REQ}"
+ cpu: "${HTTPD_CPU_REQ}"
+ limits:
+ memory: "${HTTPD_MEM_LIMIT}"
+ env:
+ - name: HTTPD_AUTH_TYPE
+ valueFrom:
+ configMapKeyRef:
+ name: "${HTTPD_SERVICE_NAME}-auth-configs"
+ key: auth-type
+ - name: HTTPD_AUTH_KERBEROS_REALMS
+ valueFrom:
+ configMapKeyRef:
+ name: "${HTTPD_SERVICE_NAME}-auth-configs"
+ key: auth-kerberos-realms
+ lifecycle:
+ postStart:
+ exec:
+ command:
+ - "/usr/bin/save-container-environment"
+ serviceAccount: cfme-httpd
+ serviceAccountName: cfme-httpd
+parameters:
+- name: NAME
+ displayName: Name
+ required: true
+ description: The name assigned to all of the frontend objects defined in this template.
+ value: cloudforms
+- name: V2_KEY
+ displayName: CloudForms Encryption Key
+ required: true
+ description: Encryption Key for CloudForms Passwords
+ from: "[a-zA-Z0-9]{43}"
+ generate: expression
+- name: DATABASE_SERVICE_NAME
+ displayName: PostgreSQL Service Name
+ required: true
+ description: The name of the OpenShift Service exposed for the PostgreSQL container.
+ value: postgresql
+- name: DATABASE_USER
+ displayName: PostgreSQL User
+ required: true
+ description: PostgreSQL user that will access the database.
+ value: root
+- name: DATABASE_PASSWORD
+ displayName: PostgreSQL Password
+ required: true
+ description: Password for the PostgreSQL user.
+ from: "[a-zA-Z0-9]{8}"
+ generate: expression
+- name: DATABASE_IP
+ displayName: PostgreSQL Server IP
+ required: true
+ description: PostgreSQL external server IP used to configure service.
+ value: ''
+- name: DATABASE_PORT
+ displayName: PostgreSQL Server Port
+ required: true
+ description: PostgreSQL external server port used to configure service.
+ value: '5432'
+- name: DATABASE_NAME
+ required: true
+ displayName: PostgreSQL Database Name
+ description: Name of the PostgreSQL database accessed.
+ value: vmdb_production
+- name: DATABASE_REGION
+ required: true
+ displayName: Application Database Region
+ description: Database region that will be used for application.
+ value: '0'
+- name: APPLICATION_ADMIN_PASSWORD
+ displayName: Application Admin Password
+ required: true
+ description: Admin password that will be set on the application.
+ value: smartvm
+- name: ANSIBLE_DATABASE_NAME
+ displayName: Ansible PostgreSQL database name
+ required: true
+ description: The database to be used by the Ansible continer
+ value: awx
+- name: MEMCACHED_SERVICE_NAME
+ required: true
+ displayName: Memcached Service Name
+ description: The name of the OpenShift Service exposed for the Memcached container.
+ value: memcached
+- name: MEMCACHED_MAX_MEMORY
+ displayName: Memcached Max Memory
+ description: Memcached maximum memory for memcached object storage in MB.
+ value: '64'
+- name: MEMCACHED_MAX_CONNECTIONS
+ displayName: Memcached Max Connections
+ description: Memcached maximum number of connections allowed.
+ value: '1024'
+- name: MEMCACHED_SLAB_PAGE_SIZE
+ displayName: Memcached Slab Page Size
+ description: Memcached size of each slab page.
+ value: 1m
+- name: ANSIBLE_SERVICE_NAME
+ displayName: Ansible Service Name
+ description: The name of the OpenShift Service exposed for the Ansible container.
+ value: ansible
+- name: ANSIBLE_ADMIN_PASSWORD
+ displayName: Ansible admin User password
+ required: true
+ description: The password for the Ansible container admin user
+ from: "[a-zA-Z0-9]{32}"
+ generate: expression
+- name: ANSIBLE_SECRET_KEY
+ displayName: Ansible Secret Key
+ required: true
+ description: Encryption key for the Ansible container
+ from: "[a-f0-9]{32}"
+ generate: expression
+- name: ANSIBLE_RABBITMQ_USER_NAME
+ displayName: RabbitMQ Username
+ required: true
+ description: Username for the Ansible RabbitMQ Server
+ value: ansible
+- name: ANSIBLE_RABBITMQ_PASSWORD
+ displayName: RabbitMQ Server Password
+ required: true
+ description: Password for the Ansible RabbitMQ Server
+ from: "[a-zA-Z0-9]{32}"
+ generate: expression
+- name: APPLICATION_CPU_REQ
+ displayName: Application Min CPU Requested
+ required: true
+ description: Minimum amount of CPU time the Application container will need (expressed in millicores).
+ value: 1000m
+- name: MEMCACHED_CPU_REQ
+ displayName: Memcached Min CPU Requested
+ required: true
+ description: Minimum amount of CPU time the Memcached container will need (expressed in millicores).
+ value: 200m
+- name: ANSIBLE_CPU_REQ
+ displayName: Ansible Min CPU Requested
+ required: true
+ description: Minimum amount of CPU time the Ansible container will need (expressed in millicores).
+ value: 1000m
+- name: APPLICATION_MEM_REQ
+ displayName: Application Min RAM Requested
+ required: true
+ description: Minimum amount of memory the Application container will need.
+ value: 6144Mi
+- name: MEMCACHED_MEM_REQ
+ displayName: Memcached Min RAM Requested
+ required: true
+ description: Minimum amount of memory the Memcached container will need.
+ value: 64Mi
+- name: ANSIBLE_MEM_REQ
+ displayName: Ansible Min RAM Requested
+ required: true
+ description: Minimum amount of memory the Ansible container will need.
+ value: 2048Mi
+- name: APPLICATION_MEM_LIMIT
+ displayName: Application Max RAM Limit
+ required: true
+ description: Maximum amount of memory the Application container can consume.
+ value: 16384Mi
+- name: MEMCACHED_MEM_LIMIT
+ displayName: Memcached Max RAM Limit
+ required: true
+ description: Maximum amount of memory the Memcached container can consume.
+ value: 256Mi
+- name: ANSIBLE_MEM_LIMIT
+ displayName: Ansible Max RAM Limit
+ required: true
+ description: Maximum amount of memory the Ansible container can consume.
+ value: 8096Mi
+- name: MEMCACHED_IMG_NAME
+ displayName: Memcached Image Name
+ description: This is the Memcached image name requested to deploy.
+ value: registry.access.redhat.com/cloudforms46-beta/cfme-openshift-memcached
+- name: MEMCACHED_IMG_TAG
+ displayName: Memcached Image Tag
+ description: This is the Memcached image tag/version requested to deploy.
+ value: latest
+- name: FRONTEND_APPLICATION_IMG_NAME
+ displayName: Frontend Application Image Name
+ description: This is the Frontend Application image name requested to deploy.
+ value: registry.access.redhat.com/cloudforms46-beta/cfme-openshift-app-ui
+- name: BACKEND_APPLICATION_IMG_NAME
+ displayName: Backend Application Image Name
+ description: This is the Backend Application image name requested to deploy.
+ value: registry.access.redhat.com/cloudforms46-beta/cfme-openshift-app
+- name: FRONTEND_APPLICATION_IMG_TAG
+ displayName: Front end Application Image Tag
+ description: This is the CloudForms Frontend Application image tag/version requested to deploy.
+ value: latest
+- name: BACKEND_APPLICATION_IMG_TAG
+ displayName: Back end Application Image Tag
+ description: This is the CloudForms Backend Application image tag/version requested to deploy.
+ value: latest
+- name: ANSIBLE_IMG_NAME
+ displayName: Ansible Image Name
+ description: This is the Ansible image name requested to deploy.
+ value: registry.access.redhat.com/cloudforms46-beta/cfme-openshift-embedded-ansible
+- name: ANSIBLE_IMG_TAG
+ displayName: Ansible Image Tag
+ description: This is the Ansible image tag/version requested to deploy.
+ value: latest
+- name: APPLICATION_DOMAIN
+ displayName: Application Hostname
+ description: The exposed hostname that will route to the application service, if left blank a value will be defaulted.
+ value: ''
+- name: APPLICATION_REPLICA_COUNT
+ displayName: Application Replica Count
+ description: This is the number of Application replicas requested to deploy.
+ value: '1'
+- name: APPLICATION_INIT_DELAY
+ displayName: Application Init Delay
+ required: true
+ description: Delay in seconds before we attempt to initialize the application.
+ value: '15'
+- name: APPLICATION_VOLUME_CAPACITY
+ displayName: Application Volume Capacity
+ required: true
+ description: Volume space available for application data.
+ value: 5Gi
+- name: HTTPD_SERVICE_NAME
+ required: true
+ displayName: Apache httpd Service Name
+ description: The name of the OpenShift Service exposed for the httpd container.
+ value: httpd
+- name: HTTPD_DBUS_API_SERVICE_NAME
+ required: true
+ displayName: Apache httpd DBus API Service Name
+ description: The name of httpd dbus api service.
+ value: httpd-dbus-api
+- name: HTTPD_IMG_NAME
+ displayName: Apache httpd Image Name
+ description: This is the httpd image name requested to deploy.
+ value: registry.access.redhat.com/cloudforms46-beta/cfme-openshift-httpd
+- name: HTTPD_IMG_TAG
+ displayName: Apache httpd Image Tag
+ description: This is the httpd image tag/version requested to deploy.
+ value: latest
+- name: HTTPD_CONFIG_DIR
+ displayName: Apache httpd Configuration Directory
+ description: Directory used to store the Apache configuration files.
+ value: "/etc/httpd/conf.d"
+- name: HTTPD_AUTH_CONFIG_DIR
+ displayName: External Authentication Configuration Directory
+ description: Directory used to store the external authentication configuration files.
+ value: "/etc/httpd/auth-conf.d"
+- name: HTTPD_CPU_REQ
+ displayName: Apache httpd Min CPU Requested
+ required: true
+ description: Minimum amount of CPU time the httpd container will need (expressed in millicores).
+ value: 500m
+- name: HTTPD_MEM_REQ
+ displayName: Apache httpd Min RAM Requested
+ required: true
+ description: Minimum amount of memory the httpd container will need.
+ value: 512Mi
+- name: HTTPD_MEM_LIMIT
+ displayName: Apache httpd Max RAM Limit
+ required: true
+ description: Maximum amount of memory the httpd container can consume.
+ value: 8192Mi
diff --git a/roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-template.yaml b/roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-template.yaml
index 3bc6c5813..5c757b6c2 100644
--- a/roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-template.yaml
+++ b/roles/openshift_examples/files/examples/v3.9/cfme-templates/cfme-template.yaml
@@ -5,17 +5,308 @@ labels:
metadata:
name: cloudforms
annotations:
- description: "CloudForms appliance with persistent storage"
- tags: "instant-app,cloudforms,cfme"
- iconClass: "icon-rails"
+ description: CloudForms appliance with persistent storage
+ tags: instant-app,cloudforms,cfme
+ iconClass: icon-rails
objects:
- apiVersion: v1
+ kind: ServiceAccount
+ metadata:
+ name: cfme-orchestrator
+- apiVersion: v1
+ kind: ServiceAccount
+ metadata:
+ name: cfme-anyuid
+- apiVersion: v1
+ kind: ServiceAccount
+ metadata:
+ name: cfme-privileged
+- apiVersion: v1
+ kind: ServiceAccount
+ metadata:
+ name: cfme-httpd
+- apiVersion: v1
+ kind: Secret
+ metadata:
+ name: "${NAME}-secrets"
+ stringData:
+ pg-password: "${DATABASE_PASSWORD}"
+ admin-password: "${APPLICATION_ADMIN_PASSWORD}"
+ database-url: postgresql://${DATABASE_USER}:${DATABASE_PASSWORD}@${DATABASE_SERVICE_NAME}/${DATABASE_NAME}?encoding=utf8&pool=5&wait_timeout=5
+ v2-key: "${V2_KEY}"
+- apiVersion: v1
+ kind: Secret
+ metadata:
+ name: "${ANSIBLE_SERVICE_NAME}-secrets"
+ stringData:
+ rabbit-password: "${ANSIBLE_RABBITMQ_PASSWORD}"
+ secret-key: "${ANSIBLE_SECRET_KEY}"
+ admin-password: "${ANSIBLE_ADMIN_PASSWORD}"
+- apiVersion: v1
+ kind: ConfigMap
+ metadata:
+ name: "${DATABASE_SERVICE_NAME}-configs"
+ data:
+ 01_miq_overrides.conf: |
+ #------------------------------------------------------------------------------
+ # CONNECTIONS AND AUTHENTICATION
+ #------------------------------------------------------------------------------
+
+ tcp_keepalives_count = 9
+ tcp_keepalives_idle = 3
+ tcp_keepalives_interval = 75
+
+ #------------------------------------------------------------------------------
+ # RESOURCE USAGE (except WAL)
+ #------------------------------------------------------------------------------
+
+ shared_preload_libraries = 'pglogical,repmgr_funcs'
+ max_worker_processes = 10
+
+ #------------------------------------------------------------------------------
+ # WRITE AHEAD LOG
+ #------------------------------------------------------------------------------
+
+ wal_level = 'logical'
+ wal_log_hints = on
+ wal_buffers = 16MB
+ checkpoint_completion_target = 0.9
+
+ #------------------------------------------------------------------------------
+ # REPLICATION
+ #------------------------------------------------------------------------------
+
+ max_wal_senders = 10
+ wal_sender_timeout = 0
+ max_replication_slots = 10
+ hot_standby = on
+
+ #------------------------------------------------------------------------------
+ # ERROR REPORTING AND LOGGING
+ #------------------------------------------------------------------------------
+
+ log_filename = 'postgresql.log'
+ log_rotation_age = 0
+ log_min_duration_statement = 5000
+ log_connections = on
+ log_disconnections = on
+ log_line_prefix = '%t:%r:%c:%u@%d:[%p]:'
+ log_lock_waits = on
+
+ #------------------------------------------------------------------------------
+ # AUTOVACUUM PARAMETERS
+ #------------------------------------------------------------------------------
+
+ log_autovacuum_min_duration = 0
+ autovacuum_naptime = 5min
+ autovacuum_vacuum_threshold = 500
+ autovacuum_analyze_threshold = 500
+ autovacuum_vacuum_scale_factor = 0.05
+
+ #------------------------------------------------------------------------------
+ # LOCK MANAGEMENT
+ #------------------------------------------------------------------------------
+
+ deadlock_timeout = 5s
+
+ #------------------------------------------------------------------------------
+ # VERSION/PLATFORM COMPATIBILITY
+ #------------------------------------------------------------------------------
+
+ escape_string_warning = off
+ standard_conforming_strings = off
+- apiVersion: v1
+ kind: ConfigMap
+ metadata:
+ name: "${HTTPD_SERVICE_NAME}-configs"
+ data:
+ application.conf: |
+ # Timeout: The number of seconds before receives and sends time out.
+ Timeout 120
+
+ RewriteEngine On
+ Options SymLinksIfOwnerMatch
+
+ <VirtualHost *:80>
+ KeepAlive on
+ # Without ServerName mod_auth_mellon compares against http:// and not https:// from the IdP
+ ServerName https://%{REQUEST_HOST}
+
+ ProxyPreserveHost on
+
+ RewriteCond %{REQUEST_URI} ^/ws [NC]
+ RewriteCond %{HTTP:UPGRADE} ^websocket$ [NC]
+ RewriteCond %{HTTP:CONNECTION} ^Upgrade$ [NC]
+ RewriteRule .* ws://${NAME}%{REQUEST_URI} [P,QSA,L]
+
+ # For httpd, some ErrorDocuments must by served by the httpd pod
+ RewriteCond %{REQUEST_URI} !^/proxy_pages
+
+ # For SAML /saml2 is only served by mod_auth_mellon in the httpd pod
+ RewriteCond %{REQUEST_URI} !^/saml2
+ RewriteRule ^/ http://${NAME}%{REQUEST_URI} [P,QSA,L]
+ ProxyPassReverse / http://${NAME}/
+
+ # Ensures httpd stdout/stderr are seen by docker logs.
+ ErrorLog "| /usr/bin/tee /proc/1/fd/2 /var/log/httpd/error_log"
+ CustomLog "| /usr/bin/tee /proc/1/fd/1 /var/log/httpd/access_log" common
+ </VirtualHost>
+ authentication.conf: |
+ # Load appropriate authentication configuration files
+ #
+ Include "conf.d/configuration-${HTTPD_AUTH_TYPE}-auth"
+ configuration-internal-auth: |
+ # Internal authentication
+ #
+ configuration-external-auth: |
+ Include "conf.d/external-auth-load-modules-conf"
+
+ <Location /dashboard/kerberos_authenticate>
+ AuthType Kerberos
+ AuthName "Kerberos Login"
+ KrbMethodNegotiate On
+ KrbMethodK5Passwd Off
+ KrbAuthRealms ${HTTPD_AUTH_KERBEROS_REALMS}
+ Krb5KeyTab /etc/http.keytab
+ KrbServiceName Any
+ Require pam-account httpd-auth
+
+ ErrorDocument 401 /proxy_pages/invalid_sso_credentials.js
+ </Location>
+
+ Include "conf.d/external-auth-login-form-conf"
+ Include "conf.d/external-auth-application-api-conf"
+ Include "conf.d/external-auth-lookup-user-details-conf"
+ Include "conf.d/external-auth-remote-user-conf"
+ configuration-active-directory-auth: |
+ Include "conf.d/external-auth-load-modules-conf"
+
+ <Location /dashboard/kerberos_authenticate>
+ AuthType Kerberos
+ AuthName "Kerberos Login"
+ KrbMethodNegotiate On
+ KrbMethodK5Passwd Off
+ KrbAuthRealms ${HTTPD_AUTH_KERBEROS_REALMS}
+ Krb5KeyTab /etc/krb5.keytab
+ KrbServiceName Any
+ Require pam-account httpd-auth
+
+ ErrorDocument 401 /proxy_pages/invalid_sso_credentials.js
+ </Location>
+
+ Include "conf.d/external-auth-login-form-conf"
+ Include "conf.d/external-auth-application-api-conf"
+ Include "conf.d/external-auth-lookup-user-details-conf"
+ Include "conf.d/external-auth-remote-user-conf"
+ configuration-saml-auth: |
+ LoadModule auth_mellon_module modules/mod_auth_mellon.so
+
+ <Location />
+ MellonEnable "info"
+
+ MellonIdPMetadataFile "/etc/httpd/saml2/idp-metadata.xml"
+
+ MellonSPPrivateKeyFile "/etc/httpd/saml2/sp-key.key"
+ MellonSPCertFile "/etc/httpd/saml2/sp-cert.cert"
+ MellonSPMetadataFile "/etc/httpd/saml2/sp-metadata.xml"
+
+ MellonVariable "sp-cookie"
+ MellonSecureCookie On
+ MellonCookiePath "/"
+
+ MellonIdP "IDP"
+
+ MellonEndpointPath "/saml2"
+
+ MellonUser username
+ MellonMergeEnvVars On
+
+ MellonSetEnvNoPrefix "REMOTE_USER" username
+ MellonSetEnvNoPrefix "REMOTE_USER_EMAIL" email
+ MellonSetEnvNoPrefix "REMOTE_USER_FIRSTNAME" firstname
+ MellonSetEnvNoPrefix "REMOTE_USER_LASTNAME" lastname
+ MellonSetEnvNoPrefix "REMOTE_USER_FULLNAME" fullname
+ MellonSetEnvNoPrefix "REMOTE_USER_GROUPS" groups
+ </Location>
+
+ <Location /saml_login>
+ AuthType "Mellon"
+ MellonEnable "auth"
+ Require valid-user
+ </Location>
+
+ Include "conf.d/external-auth-remote-user-conf"
+ external-auth-load-modules-conf: |
+ LoadModule authnz_pam_module modules/mod_authnz_pam.so
+ LoadModule intercept_form_submit_module modules/mod_intercept_form_submit.so
+ LoadModule lookup_identity_module modules/mod_lookup_identity.so
+ LoadModule auth_kerb_module modules/mod_auth_kerb.so
+ external-auth-login-form-conf: |
+ <Location /dashboard/external_authenticate>
+ InterceptFormPAMService httpd-auth
+ InterceptFormLogin user_name
+ InterceptFormPassword user_password
+ InterceptFormLoginSkip admin
+ InterceptFormClearRemoteUserForSkipped on
+ </Location>
+ external-auth-application-api-conf: |
+ <LocationMatch ^/api>
+ SetEnvIf Authorization '^Basic +YWRtaW46' let_admin_in
+ SetEnvIf X-Auth-Token '^.+$' let_api_token_in
+ SetEnvIf X-MIQ-Token '^.+$' let_sys_token_in
+
+ AuthType Basic
+ AuthName "External Authentication (httpd) for API"
+ AuthBasicProvider PAM
+
+ AuthPAMService httpd-auth
+ Require valid-user
+ Order Allow,Deny
+ Allow from env=let_admin_in
+ Allow from env=let_api_token_in
+ Allow from env=let_sys_token_in
+ Satisfy Any
+ </LocationMatch>
+ external-auth-lookup-user-details-conf: |
+ <LocationMatch ^/dashboard/external_authenticate$|^/dashboard/kerberos_authenticate$|^/api>
+ LookupUserAttr mail REMOTE_USER_EMAIL
+ LookupUserAttr givenname REMOTE_USER_FIRSTNAME
+ LookupUserAttr sn REMOTE_USER_LASTNAME
+ LookupUserAttr displayname REMOTE_USER_FULLNAME
+ LookupUserAttr domainname REMOTE_USER_DOMAIN
+
+ LookupUserGroups REMOTE_USER_GROUPS ":"
+ LookupDbusTimeout 5000
+ </LocationMatch>
+ external-auth-remote-user-conf: |
+ RequestHeader unset X_REMOTE_USER
+
+ RequestHeader set X_REMOTE_USER %{REMOTE_USER}e env=REMOTE_USER
+ RequestHeader set X_EXTERNAL_AUTH_ERROR %{EXTERNAL_AUTH_ERROR}e env=EXTERNAL_AUTH_ERROR
+ RequestHeader set X_REMOTE_USER_EMAIL %{REMOTE_USER_EMAIL}e env=REMOTE_USER_EMAIL
+ RequestHeader set X_REMOTE_USER_FIRSTNAME %{REMOTE_USER_FIRSTNAME}e env=REMOTE_USER_FIRSTNAME
+ RequestHeader set X_REMOTE_USER_LASTNAME %{REMOTE_USER_LASTNAME}e env=REMOTE_USER_LASTNAME
+ RequestHeader set X_REMOTE_USER_FULLNAME %{REMOTE_USER_FULLNAME}e env=REMOTE_USER_FULLNAME
+ RequestHeader set X_REMOTE_USER_GROUPS %{REMOTE_USER_GROUPS}e env=REMOTE_USER_GROUPS
+ RequestHeader set X_REMOTE_USER_DOMAIN %{REMOTE_USER_DOMAIN}e env=REMOTE_USER_DOMAIN
+- apiVersion: v1
+ kind: ConfigMap
+ metadata:
+ name: "${HTTPD_SERVICE_NAME}-auth-configs"
+ data:
+ auth-type: internal
+ auth-kerberos-realms: undefined
+ auth-configuration.conf: |
+ # External Authentication Configuration File
+ #
+ # For details on usage please see https://github.com/ManageIQ/manageiq-pods/blob/master/README.md#configuring-external-authentication
+- apiVersion: v1
kind: Service
metadata:
annotations:
- description: "Exposes and load balances CloudForms pods"
+ description: Exposes and load balances CloudForms pods
service.alpha.openshift.io/dependencies: '[{"name":"${DATABASE_SERVICE_NAME}","namespace":"","kind":"Service"},{"name":"${MEMCACHED_SERVICE_NAME}","namespace":"","kind":"Service"}]'
- name: ${NAME}
+ name: "${NAME}"
spec:
clusterIP: None
ports:
@@ -23,141 +314,97 @@ objects:
port: 80
protocol: TCP
targetPort: 80
- - name: https
- port: 443
- protocol: TCP
- targetPort: 443
selector:
- name: ${NAME}
+ name: "${NAME}"
- apiVersion: v1
kind: Route
metadata:
- name: ${NAME}
+ name: "${HTTPD_SERVICE_NAME}"
spec:
- host: ${APPLICATION_DOMAIN}
+ host: "${APPLICATION_DOMAIN}"
port:
- targetPort: https
+ targetPort: http
tls:
- termination: passthrough
+ termination: edge
+ insecureEdgeTerminationPolicy: Redirect
to:
kind: Service
- name: ${NAME}
-- apiVersion: v1
- kind: ImageStream
- metadata:
- name: cfme-openshift-app
- annotations:
- description: "Keeps track of changes in the CloudForms app image"
- spec:
- dockerImageRepository: "${APPLICATION_IMG_NAME}"
-- apiVersion: v1
- kind: ImageStream
- metadata:
- name: cfme-openshift-postgresql
- annotations:
- description: "Keeps track of changes in the CloudForms postgresql image"
- spec:
- dockerImageRepository: "${POSTGRESQL_IMG_NAME}"
-- apiVersion: v1
- kind: ImageStream
- metadata:
- name: cfme-openshift-memcached
- annotations:
- description: "Keeps track of changes in the CloudForms memcached image"
- spec:
- dockerImageRepository: "${MEMCACHED_IMG_NAME}"
+ name: "${HTTPD_SERVICE_NAME}"
- apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: "${NAME}-${DATABASE_SERVICE_NAME}"
spec:
accessModes:
- - ReadWriteOnce
+ - ReadWriteOnce
resources:
requests:
- storage: ${DATABASE_VOLUME_CAPACITY}
-- apiVersion: v1
- kind: PersistentVolumeClaim
- metadata:
- name: "${NAME}-region"
- spec:
- accessModes:
- - ReadWriteOnce
- resources:
- requests:
- storage: ${APPLICATION_REGION_VOLUME_CAPACITY}
+ storage: "${DATABASE_VOLUME_CAPACITY}"
- apiVersion: apps/v1beta1
- kind: "StatefulSet"
+ kind: StatefulSet
metadata:
- name: ${NAME}
+ name: "${NAME}"
annotations:
- description: "Defines how to deploy the CloudForms appliance"
+ description: Defines how to deploy the CloudForms appliance
spec:
serviceName: "${NAME}"
- replicas: 1
+ replicas: "${APPLICATION_REPLICA_COUNT}"
template:
metadata:
labels:
- name: ${NAME}
- name: ${NAME}
+ name: "${NAME}"
+ name: "${NAME}"
spec:
containers:
- name: cloudforms
- image: "${APPLICATION_IMG_NAME}:${APPLICATION_IMG_TAG}"
+ image: "${FRONTEND_APPLICATION_IMG_NAME}:${FRONTEND_APPLICATION_IMG_TAG}"
livenessProbe:
- tcpSocket:
- port: 443
+ exec:
+ command:
+ - pidof
+ - MIQ Server
initialDelaySeconds: 480
timeoutSeconds: 3
readinessProbe:
- httpGet:
- path: /
- port: 443
- scheme: HTTPS
+ tcpSocket:
+ port: 80
initialDelaySeconds: 200
timeoutSeconds: 3
ports:
- containerPort: 80
protocol: TCP
- - containerPort: 443
- protocol: TCP
- securityContext:
- privileged: true
volumeMounts:
- -
- name: "${NAME}-server"
- mountPath: "/persistent"
- -
- name: "${NAME}-region"
- mountPath: "/persistent-region"
+ - name: "${NAME}-server"
+ mountPath: "/persistent"
env:
- -
- name: "APPLICATION_INIT_DELAY"
- value: "${APPLICATION_INIT_DELAY}"
- -
- name: "DATABASE_SERVICE_NAME"
- value: "${DATABASE_SERVICE_NAME}"
- -
- name: "DATABASE_REGION"
- value: "${DATABASE_REGION}"
- -
- name: "MEMCACHED_SERVICE_NAME"
- value: "${MEMCACHED_SERVICE_NAME}"
- -
- name: "POSTGRESQL_USER"
- value: "${DATABASE_USER}"
- -
- name: "POSTGRESQL_PASSWORD"
- value: "${DATABASE_PASSWORD}"
- -
- name: "POSTGRESQL_DATABASE"
- value: "${DATABASE_NAME}"
- -
- name: "POSTGRESQL_MAX_CONNECTIONS"
- value: "${POSTGRESQL_MAX_CONNECTIONS}"
- -
- name: "POSTGRESQL_SHARED_BUFFERS"
- value: "${POSTGRESQL_SHARED_BUFFERS}"
+ - name: MY_POD_NAMESPACE
+ valueFrom:
+ fieldRef:
+ fieldPath: metadata.namespace
+ - name: APPLICATION_INIT_DELAY
+ value: "${APPLICATION_INIT_DELAY}"
+ - name: DATABASE_REGION
+ value: "${DATABASE_REGION}"
+ - name: DATABASE_URL
+ valueFrom:
+ secretKeyRef:
+ name: "${NAME}-secrets"
+ key: database-url
+ - name: V2_KEY
+ valueFrom:
+ secretKeyRef:
+ name: "${NAME}-secrets"
+ key: v2-key
+ - name: APPLICATION_ADMIN_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: "${NAME}-secrets"
+ key: admin-password
+ - name: ANSIBLE_ADMIN_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: "${ANSIBLE_SERVICE_NAME}-secrets"
+ key: admin-password
resources:
requests:
memory: "${APPLICATION_MEM_REQ}"
@@ -168,59 +415,128 @@ objects:
preStop:
exec:
command:
- - /opt/rh/cfme-container-scripts/sync-pv-data
- volumes:
- -
- name: "${NAME}-region"
- persistentVolumeClaim:
- claimName: ${NAME}-region
+ - "/opt/rh/cfme-container-scripts/sync-pv-data"
+ serviceAccount: cfme-orchestrator
+ serviceAccountName: cfme-orchestrator
+ terminationGracePeriodSeconds: 90
volumeClaimTemplates:
- - metadata:
- name: "${NAME}-server"
- annotations:
- # Uncomment this if using dynamic volume provisioning.
- # https://docs.openshift.org/latest/install_config/persistent_storage/dynamically_provisioning_pvs.html
- # volume.alpha.kubernetes.io/storage-class: anything
- spec:
- accessModes: [ ReadWriteOnce ]
+ - metadata:
+ name: "${NAME}-server"
+ annotations:
+ spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: "${APPLICATION_VOLUME_CAPACITY}"
+- apiVersion: v1
+ kind: Service
+ metadata:
+ annotations:
+ description: Headless service for CloudForms backend pods
+ name: "${NAME}-backend"
+ spec:
+ clusterIP: None
+ selector:
+ name: "${NAME}-backend"
+- apiVersion: apps/v1beta1
+ kind: StatefulSet
+ metadata:
+ name: "${NAME}-backend"
+ annotations:
+ description: Defines how to deploy the CloudForms appliance
+ spec:
+ serviceName: "${NAME}-backend"
+ replicas: 0
+ template:
+ metadata:
+ labels:
+ name: "${NAME}-backend"
+ name: "${NAME}-backend"
+ spec:
+ containers:
+ - name: cloudforms
+ image: "${BACKEND_APPLICATION_IMG_NAME}:${BACKEND_APPLICATION_IMG_TAG}"
+ livenessProbe:
+ exec:
+ command:
+ - pidof
+ - MIQ Server
+ initialDelaySeconds: 480
+ timeoutSeconds: 3
+ volumeMounts:
+ - name: "${NAME}-server"
+ mountPath: "/persistent"
+ env:
+ - name: APPLICATION_INIT_DELAY
+ value: "${APPLICATION_INIT_DELAY}"
+ - name: DATABASE_URL
+ valueFrom:
+ secretKeyRef:
+ name: "${NAME}-secrets"
+ key: database-url
+ - name: MIQ_SERVER_DEFAULT_ROLES
+ value: database_operations,event,reporting,scheduler,smartstate,ems_operations,ems_inventory,automate
+ - name: FRONTEND_SERVICE_NAME
+ value: "${NAME}"
+ - name: V2_KEY
+ valueFrom:
+ secretKeyRef:
+ name: "${NAME}-secrets"
+ key: v2-key
+ - name: ANSIBLE_ADMIN_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: "${ANSIBLE_SERVICE_NAME}-secrets"
+ key: admin-password
resources:
requests:
- storage: "${APPLICATION_VOLUME_CAPACITY}"
+ memory: "${APPLICATION_MEM_REQ}"
+ cpu: "${APPLICATION_CPU_REQ}"
+ limits:
+ memory: "${APPLICATION_MEM_LIMIT}"
+ lifecycle:
+ preStop:
+ exec:
+ command:
+ - "/opt/rh/cfme-container-scripts/sync-pv-data"
+ serviceAccount: cfme-orchestrator
+ serviceAccountName: cfme-orchestrator
+ terminationGracePeriodSeconds: 90
+ volumeClaimTemplates:
+ - metadata:
+ name: "${NAME}-server"
+ annotations:
+ spec:
+ accessModes:
+ - ReadWriteOnce
+ resources:
+ requests:
+ storage: "${APPLICATION_VOLUME_CAPACITY}"
- apiVersion: v1
- kind: "Service"
+ kind: Service
metadata:
name: "${MEMCACHED_SERVICE_NAME}"
annotations:
- description: "Exposes the memcached server"
+ description: Exposes the memcached server
spec:
ports:
- -
- name: "memcached"
- port: 11211
- targetPort: 11211
+ - name: memcached
+ port: 11211
+ targetPort: 11211
selector:
name: "${MEMCACHED_SERVICE_NAME}"
- apiVersion: v1
- kind: "DeploymentConfig"
+ kind: DeploymentConfig
metadata:
name: "${MEMCACHED_SERVICE_NAME}"
annotations:
- description: "Defines how to deploy memcached"
+ description: Defines how to deploy memcached
spec:
strategy:
- type: "Recreate"
+ type: Recreate
triggers:
- -
- type: "ImageChange"
- imageChangeParams:
- automatic: true
- containerNames:
- - "memcached"
- from:
- kind: "ImageStreamTag"
- name: "cfme-openshift-memcached:${MEMCACHED_IMG_TAG}"
- -
- type: "ConfigChange"
+ - type: ConfigChange
replicas: 1
selector:
name: "${MEMCACHED_SERVICE_NAME}"
@@ -232,74 +548,58 @@ objects:
spec:
volumes: []
containers:
- -
- name: "memcached"
- image: "${MEMCACHED_IMG_NAME}:${MEMCACHED_IMG_TAG}"
- ports:
- -
- containerPort: 11211
- readinessProbe:
- timeoutSeconds: 1
- initialDelaySeconds: 5
- tcpSocket:
- port: 11211
- livenessProbe:
- timeoutSeconds: 1
- initialDelaySeconds: 30
- tcpSocket:
- port: 11211
- volumeMounts: []
- env:
- -
- name: "MEMCACHED_MAX_MEMORY"
- value: "${MEMCACHED_MAX_MEMORY}"
- -
- name: "MEMCACHED_MAX_CONNECTIONS"
- value: "${MEMCACHED_MAX_CONNECTIONS}"
- -
- name: "MEMCACHED_SLAB_PAGE_SIZE"
- value: "${MEMCACHED_SLAB_PAGE_SIZE}"
- resources:
- requests:
- memory: "${MEMCACHED_MEM_REQ}"
- cpu: "${MEMCACHED_CPU_REQ}"
- limits:
- memory: "${MEMCACHED_MEM_LIMIT}"
+ - name: memcached
+ image: "${MEMCACHED_IMG_NAME}:${MEMCACHED_IMG_TAG}"
+ ports:
+ - containerPort: 11211
+ readinessProbe:
+ timeoutSeconds: 1
+ initialDelaySeconds: 5
+ tcpSocket:
+ port: 11211
+ livenessProbe:
+ timeoutSeconds: 1
+ initialDelaySeconds: 30
+ tcpSocket:
+ port: 11211
+ volumeMounts: []
+ env:
+ - name: MEMCACHED_MAX_MEMORY
+ value: "${MEMCACHED_MAX_MEMORY}"
+ - name: MEMCACHED_MAX_CONNECTIONS
+ value: "${MEMCACHED_MAX_CONNECTIONS}"
+ - name: MEMCACHED_SLAB_PAGE_SIZE
+ value: "${MEMCACHED_SLAB_PAGE_SIZE}"
+ resources:
+ requests:
+ memory: "${MEMCACHED_MEM_REQ}"
+ cpu: "${MEMCACHED_CPU_REQ}"
+ limits:
+ memory: "${MEMCACHED_MEM_LIMIT}"
- apiVersion: v1
- kind: "Service"
+ kind: Service
metadata:
name: "${DATABASE_SERVICE_NAME}"
annotations:
- description: "Exposes the database server"
+ description: Exposes the database server
spec:
ports:
- -
- name: "postgresql"
- port: 5432
- targetPort: 5432
+ - name: postgresql
+ port: 5432
+ targetPort: 5432
selector:
name: "${DATABASE_SERVICE_NAME}"
- apiVersion: v1
- kind: "DeploymentConfig"
+ kind: DeploymentConfig
metadata:
name: "${DATABASE_SERVICE_NAME}"
annotations:
- description: "Defines how to deploy the database"
+ description: Defines how to deploy the database
spec:
strategy:
- type: "Recreate"
+ type: Recreate
triggers:
- -
- type: "ImageChange"
- imageChangeParams:
- automatic: true
- containerNames:
- - "postgresql"
- from:
- kind: "ImageStreamTag"
- name: "cfme-openshift-postgresql:${POSTGRESQL_IMG_TAG}"
- -
- type: "ConfigChange"
+ - type: ConfigChange
replicas: 1
selector:
name: "${DATABASE_SERVICE_NAME}"
@@ -310,236 +610,524 @@ objects:
name: "${DATABASE_SERVICE_NAME}"
spec:
volumes:
- -
- name: "cfme-pgdb-volume"
- persistentVolumeClaim:
- claimName: "${NAME}-${DATABASE_SERVICE_NAME}"
+ - name: cfme-pgdb-volume
+ persistentVolumeClaim:
+ claimName: "${NAME}-${DATABASE_SERVICE_NAME}"
+ - name: cfme-pg-configs
+ configMap:
+ name: "${DATABASE_SERVICE_NAME}-configs"
containers:
- -
- name: "postgresql"
- image: "${POSTGRESQL_IMG_NAME}:${POSTGRESQL_IMG_TAG}"
- ports:
- -
- containerPort: 5432
- readinessProbe:
- timeoutSeconds: 1
- initialDelaySeconds: 15
+ - name: postgresql
+ image: "${POSTGRESQL_IMG_NAME}:${POSTGRESQL_IMG_TAG}"
+ ports:
+ - containerPort: 5432
+ readinessProbe:
+ timeoutSeconds: 1
+ initialDelaySeconds: 15
+ exec:
+ command:
+ - "/bin/sh"
+ - "-i"
+ - "-c"
+ - psql -h 127.0.0.1 -U ${POSTGRESQL_USER} -q -d ${POSTGRESQL_DATABASE} -c 'SELECT 1'
+ livenessProbe:
+ timeoutSeconds: 1
+ initialDelaySeconds: 60
+ tcpSocket:
+ port: 5432
+ volumeMounts:
+ - name: cfme-pgdb-volume
+ mountPath: "/var/lib/pgsql/data"
+ - name: cfme-pg-configs
+ mountPath: "${POSTGRESQL_CONFIG_DIR}"
+ env:
+ - name: POSTGRESQL_USER
+ value: "${DATABASE_USER}"
+ - name: POSTGRESQL_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: "${NAME}-secrets"
+ key: pg-password
+ - name: POSTGRESQL_DATABASE
+ value: "${DATABASE_NAME}"
+ - name: POSTGRESQL_MAX_CONNECTIONS
+ value: "${POSTGRESQL_MAX_CONNECTIONS}"
+ - name: POSTGRESQL_SHARED_BUFFERS
+ value: "${POSTGRESQL_SHARED_BUFFERS}"
+ - name: POSTGRESQL_CONFIG_DIR
+ value: "${POSTGRESQL_CONFIG_DIR}"
+ resources:
+ requests:
+ memory: "${POSTGRESQL_MEM_REQ}"
+ cpu: "${POSTGRESQL_CPU_REQ}"
+ limits:
+ memory: "${POSTGRESQL_MEM_LIMIT}"
+- apiVersion: v1
+ kind: Service
+ metadata:
+ annotations:
+ description: Exposes and load balances Ansible pods
+ service.alpha.openshift.io/dependencies: '[{"name":"${DATABASE_SERVICE_NAME}","namespace":"","kind":"Service"}]'
+ name: "${ANSIBLE_SERVICE_NAME}"
+ spec:
+ ports:
+ - name: http
+ port: 80
+ protocol: TCP
+ targetPort: 80
+ - name: https
+ port: 443
+ protocol: TCP
+ targetPort: 443
+ selector:
+ name: "${ANSIBLE_SERVICE_NAME}"
+- apiVersion: v1
+ kind: DeploymentConfig
+ metadata:
+ name: "${ANSIBLE_SERVICE_NAME}"
+ annotations:
+ description: Defines how to deploy the Ansible appliance
+ spec:
+ strategy:
+ type: Recreate
+ serviceName: "${ANSIBLE_SERVICE_NAME}"
+ replicas: 0
+ template:
+ metadata:
+ labels:
+ name: "${ANSIBLE_SERVICE_NAME}"
+ name: "${ANSIBLE_SERVICE_NAME}"
+ spec:
+ containers:
+ - name: ansible
+ image: "${ANSIBLE_IMG_NAME}:${ANSIBLE_IMG_TAG}"
+ livenessProbe:
+ tcpSocket:
+ port: 443
+ initialDelaySeconds: 480
+ timeoutSeconds: 3
+ readinessProbe:
+ httpGet:
+ path: "/"
+ port: 443
+ scheme: HTTPS
+ initialDelaySeconds: 200
+ timeoutSeconds: 3
+ ports:
+ - containerPort: 80
+ protocol: TCP
+ - containerPort: 443
+ protocol: TCP
+ securityContext:
+ privileged: true
+ env:
+ - name: ADMIN_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: "${ANSIBLE_SERVICE_NAME}-secrets"
+ key: admin-password
+ - name: RABBITMQ_USER_NAME
+ value: "${ANSIBLE_RABBITMQ_USER_NAME}"
+ - name: RABBITMQ_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: "${ANSIBLE_SERVICE_NAME}-secrets"
+ key: rabbit-password
+ - name: ANSIBLE_SECRET_KEY
+ valueFrom:
+ secretKeyRef:
+ name: "${ANSIBLE_SERVICE_NAME}-secrets"
+ key: secret-key
+ - name: DATABASE_SERVICE_NAME
+ value: "${DATABASE_SERVICE_NAME}"
+ - name: POSTGRESQL_USER
+ value: "${DATABASE_USER}"
+ - name: POSTGRESQL_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: "${NAME}-secrets"
+ key: pg-password
+ - name: POSTGRESQL_DATABASE
+ value: "${ANSIBLE_DATABASE_NAME}"
+ resources:
+ requests:
+ memory: "${ANSIBLE_MEM_REQ}"
+ cpu: "${ANSIBLE_CPU_REQ}"
+ limits:
+ memory: "${ANSIBLE_MEM_LIMIT}"
+ serviceAccount: cfme-privileged
+ serviceAccountName: cfme-privileged
+- apiVersion: v1
+ kind: Service
+ metadata:
+ name: "${HTTPD_SERVICE_NAME}"
+ annotations:
+ description: Exposes the httpd server
+ service.alpha.openshift.io/dependencies: '[{"name":"${NAME}","namespace":"","kind":"Service"}]'
+ spec:
+ ports:
+ - name: http
+ port: 80
+ targetPort: 80
+ selector:
+ name: httpd
+- apiVersion: v1
+ kind: Service
+ metadata:
+ name: "${HTTPD_DBUS_API_SERVICE_NAME}"
+ annotations:
+ description: Exposes the httpd server dbus api
+ service.alpha.openshift.io/dependencies: '[{"name":"${NAME}","namespace":"","kind":"Service"}]'
+ spec:
+ ports:
+ - name: http-dbus-api
+ port: 8080
+ targetPort: 8080
+ selector:
+ name: httpd
+- apiVersion: v1
+ kind: DeploymentConfig
+ metadata:
+ name: "${HTTPD_SERVICE_NAME}"
+ annotations:
+ description: Defines how to deploy httpd
+ spec:
+ strategy:
+ type: Recreate
+ recreateParams:
+ timeoutSeconds: 1200
+ triggers:
+ - type: ConfigChange
+ replicas: 1
+ selector:
+ name: "${HTTPD_SERVICE_NAME}"
+ template:
+ metadata:
+ name: "${HTTPD_SERVICE_NAME}"
+ labels:
+ name: "${HTTPD_SERVICE_NAME}"
+ spec:
+ volumes:
+ - name: httpd-config
+ configMap:
+ name: "${HTTPD_SERVICE_NAME}-configs"
+ - name: httpd-auth-config
+ configMap:
+ name: "${HTTPD_SERVICE_NAME}-auth-configs"
+ containers:
+ - name: httpd
+ image: "${HTTPD_IMG_NAME}:${HTTPD_IMG_TAG}"
+ ports:
+ - containerPort: 80
+ protocol: TCP
+ - containerPort: 8080
+ protocol: TCP
+ livenessProbe:
+ exec:
+ command:
+ - pidof
+ - httpd
+ initialDelaySeconds: 15
+ timeoutSeconds: 3
+ readinessProbe:
+ tcpSocket:
+ port: 80
+ initialDelaySeconds: 10
+ timeoutSeconds: 3
+ volumeMounts:
+ - name: httpd-config
+ mountPath: "${HTTPD_CONFIG_DIR}"
+ - name: httpd-auth-config
+ mountPath: "${HTTPD_AUTH_CONFIG_DIR}"
+ resources:
+ requests:
+ memory: "${HTTPD_MEM_REQ}"
+ cpu: "${HTTPD_CPU_REQ}"
+ limits:
+ memory: "${HTTPD_MEM_LIMIT}"
+ env:
+ - name: HTTPD_AUTH_TYPE
+ valueFrom:
+ configMapKeyRef:
+ name: "${HTTPD_SERVICE_NAME}-auth-configs"
+ key: auth-type
+ - name: HTTPD_AUTH_KERBEROS_REALMS
+ valueFrom:
+ configMapKeyRef:
+ name: "${HTTPD_SERVICE_NAME}-auth-configs"
+ key: auth-kerberos-realms
+ lifecycle:
+ postStart:
exec:
command:
- - "/bin/sh"
- - "-i"
- - "-c"
- - "psql -h 127.0.0.1 -U ${POSTGRESQL_USER} -q -d ${POSTGRESQL_DATABASE} -c 'SELECT 1'"
- livenessProbe:
- timeoutSeconds: 1
- initialDelaySeconds: 60
- tcpSocket:
- port: 5432
- volumeMounts:
- -
- name: "cfme-pgdb-volume"
- mountPath: "/var/lib/pgsql/data"
- env:
- -
- name: "POSTGRESQL_USER"
- value: "${DATABASE_USER}"
- -
- name: "POSTGRESQL_PASSWORD"
- value: "${DATABASE_PASSWORD}"
- -
- name: "POSTGRESQL_DATABASE"
- value: "${DATABASE_NAME}"
- -
- name: "POSTGRESQL_MAX_CONNECTIONS"
- value: "${POSTGRESQL_MAX_CONNECTIONS}"
- -
- name: "POSTGRESQL_SHARED_BUFFERS"
- value: "${POSTGRESQL_SHARED_BUFFERS}"
- resources:
- requests:
- memory: "${POSTGRESQL_MEM_REQ}"
- cpu: "${POSTGRESQL_CPU_REQ}"
- limits:
- memory: "${POSTGRESQL_MEM_LIMIT}"
-
+ - "/usr/bin/save-container-environment"
+ serviceAccount: cfme-httpd
+ serviceAccountName: cfme-httpd
parameters:
- -
- name: "NAME"
- displayName: Name
- required: true
- description: "The name assigned to all of the frontend objects defined in this template."
- value: cloudforms
- -
- name: "DATABASE_SERVICE_NAME"
- displayName: "PostgreSQL Service Name"
- required: true
- description: "The name of the OpenShift Service exposed for the PostgreSQL container."
- value: "postgresql"
- -
- name: "DATABASE_USER"
- displayName: "PostgreSQL User"
- required: true
- description: "PostgreSQL user that will access the database."
- value: "root"
- -
- name: "DATABASE_PASSWORD"
- displayName: "PostgreSQL Password"
- required: true
- description: "Password for the PostgreSQL user."
- value: "smartvm"
- -
- name: "DATABASE_NAME"
- required: true
- displayName: "PostgreSQL Database Name"
- description: "Name of the PostgreSQL database accessed."
- value: "vmdb_production"
- -
- name: "DATABASE_REGION"
- required: true
- displayName: "Application Database Region"
- description: "Database region that will be used for application."
- value: "0"
- -
- name: "MEMCACHED_SERVICE_NAME"
- required: true
- displayName: "Memcached Service Name"
- description: "The name of the OpenShift Service exposed for the Memcached container."
- value: "memcached"
- -
- name: "MEMCACHED_MAX_MEMORY"
- displayName: "Memcached Max Memory"
- description: "Memcached maximum memory for memcached object storage in MB."
- value: "64"
- -
- name: "MEMCACHED_MAX_CONNECTIONS"
- displayName: "Memcached Max Connections"
- description: "Memcached maximum number of connections allowed."
- value: "1024"
- -
- name: "MEMCACHED_SLAB_PAGE_SIZE"
- displayName: "Memcached Slab Page Size"
- description: "Memcached size of each slab page."
- value: "1m"
- -
- name: "POSTGRESQL_MAX_CONNECTIONS"
- displayName: "PostgreSQL Max Connections"
- description: "PostgreSQL maximum number of database connections allowed."
- value: "100"
- -
- name: "POSTGRESQL_SHARED_BUFFERS"
- displayName: "PostgreSQL Shared Buffer Amount"
- description: "Amount of memory dedicated for PostgreSQL shared memory buffers."
- value: "256MB"
- -
- name: "APPLICATION_CPU_REQ"
- displayName: "Application Min CPU Requested"
- required: true
- description: "Minimum amount of CPU time the Application container will need (expressed in millicores)."
- value: "1000m"
- -
- name: "POSTGRESQL_CPU_REQ"
- displayName: "PostgreSQL Min CPU Requested"
- required: true
- description: "Minimum amount of CPU time the PostgreSQL container will need (expressed in millicores)."
- value: "500m"
- -
- name: "MEMCACHED_CPU_REQ"
- displayName: "Memcached Min CPU Requested"
- required: true
- description: "Minimum amount of CPU time the Memcached container will need (expressed in millicores)."
- value: "200m"
- -
- name: "APPLICATION_MEM_REQ"
- displayName: "Application Min RAM Requested"
- required: true
- description: "Minimum amount of memory the Application container will need."
- value: "6144Mi"
- -
- name: "POSTGRESQL_MEM_REQ"
- displayName: "PostgreSQL Min RAM Requested"
- required: true
- description: "Minimum amount of memory the PostgreSQL container will need."
- value: "1024Mi"
- -
- name: "MEMCACHED_MEM_REQ"
- displayName: "Memcached Min RAM Requested"
- required: true
- description: "Minimum amount of memory the Memcached container will need."
- value: "64Mi"
- -
- name: "APPLICATION_MEM_LIMIT"
- displayName: "Application Max RAM Limit"
- required: true
- description: "Maximum amount of memory the Application container can consume."
- value: "16384Mi"
- -
- name: "POSTGRESQL_MEM_LIMIT"
- displayName: "PostgreSQL Max RAM Limit"
- required: true
- description: "Maximum amount of memory the PostgreSQL container can consume."
- value: "8192Mi"
- -
- name: "MEMCACHED_MEM_LIMIT"
- displayName: "Memcached Max RAM Limit"
- required: true
- description: "Maximum amount of memory the Memcached container can consume."
- value: "256Mi"
- -
- name: "POSTGRESQL_IMG_NAME"
- displayName: "PostgreSQL Image Name"
- description: "This is the PostgreSQL image name requested to deploy."
- value: "registry.access.redhat.com/cloudforms45/cfme-openshift-postgresql"
- -
- name: "POSTGRESQL_IMG_TAG"
- displayName: "PostgreSQL Image Tag"
- description: "This is the PostgreSQL image tag/version requested to deploy."
- value: "latest"
- -
- name: "MEMCACHED_IMG_NAME"
- displayName: "Memcached Image Name"
- description: "This is the Memcached image name requested to deploy."
- value: "registry.access.redhat.com/cloudforms45/cfme-openshift-memcached"
- -
- name: "MEMCACHED_IMG_TAG"
- displayName: "Memcached Image Tag"
- description: "This is the Memcached image tag/version requested to deploy."
- value: "latest"
- -
- name: "APPLICATION_IMG_NAME"
- displayName: "Application Image Name"
- description: "This is the Application image name requested to deploy."
- value: "registry.access.redhat.com/cloudforms45/cfme-openshift-app"
- -
- name: "APPLICATION_IMG_TAG"
- displayName: "Application Image Tag"
- description: "This is the Application image tag/version requested to deploy."
- value: "latest"
- -
- name: "APPLICATION_DOMAIN"
- displayName: "Application Hostname"
- description: "The exposed hostname that will route to the application service, if left blank a value will be defaulted."
- value: ""
- -
- name: "APPLICATION_INIT_DELAY"
- displayName: "Application Init Delay"
- required: true
- description: "Delay in seconds before we attempt to initialize the application."
- value: "15"
- -
- name: "APPLICATION_VOLUME_CAPACITY"
- displayName: "Application Volume Capacity"
- required: true
- description: "Volume space available for application data."
- value: "5Gi"
- -
- name: "APPLICATION_REGION_VOLUME_CAPACITY"
- displayName: "Application Region Volume Capacity"
- required: true
- description: "Volume space available for region application data."
- value: "5Gi"
- -
- name: "DATABASE_VOLUME_CAPACITY"
- displayName: "Database Volume Capacity"
- required: true
- description: "Volume space available for database."
- value: "15Gi"
+- name: NAME
+ displayName: Name
+ required: true
+ description: The name assigned to all of the frontend objects defined in this template.
+ value: cloudforms
+- name: V2_KEY
+ displayName: CloudForms Encryption Key
+ required: true
+ description: Encryption Key for CloudForms Passwords
+ from: "[a-zA-Z0-9]{43}"
+ generate: expression
+- name: DATABASE_SERVICE_NAME
+ displayName: PostgreSQL Service Name
+ required: true
+ description: The name of the OpenShift Service exposed for the PostgreSQL container.
+ value: postgresql
+- name: DATABASE_USER
+ displayName: PostgreSQL User
+ required: true
+ description: PostgreSQL user that will access the database.
+ value: root
+- name: DATABASE_PASSWORD
+ displayName: PostgreSQL Password
+ required: true
+ description: Password for the PostgreSQL user.
+ from: "[a-zA-Z0-9]{8}"
+ generate: expression
+- name: DATABASE_NAME
+ required: true
+ displayName: PostgreSQL Database Name
+ description: Name of the PostgreSQL database accessed.
+ value: vmdb_production
+- name: DATABASE_REGION
+ required: true
+ displayName: Application Database Region
+ description: Database region that will be used for application.
+ value: '0'
+- name: APPLICATION_ADMIN_PASSWORD
+ displayName: Application Admin Password
+ required: true
+ description: Admin password that will be set on the application.
+ value: smartvm
+- name: ANSIBLE_DATABASE_NAME
+ displayName: Ansible PostgreSQL database name
+ required: true
+ description: The database to be used by the Ansible continer
+ value: awx
+- name: MEMCACHED_SERVICE_NAME
+ required: true
+ displayName: Memcached Service Name
+ description: The name of the OpenShift Service exposed for the Memcached container.
+ value: memcached
+- name: MEMCACHED_MAX_MEMORY
+ displayName: Memcached Max Memory
+ description: Memcached maximum memory for memcached object storage in MB.
+ value: '64'
+- name: MEMCACHED_MAX_CONNECTIONS
+ displayName: Memcached Max Connections
+ description: Memcached maximum number of connections allowed.
+ value: '1024'
+- name: MEMCACHED_SLAB_PAGE_SIZE
+ displayName: Memcached Slab Page Size
+ description: Memcached size of each slab page.
+ value: 1m
+- name: POSTGRESQL_CONFIG_DIR
+ displayName: PostgreSQL Configuration Overrides
+ description: Directory used to store PostgreSQL configuration overrides.
+ value: "/var/lib/pgsql/conf.d"
+- name: POSTGRESQL_MAX_CONNECTIONS
+ displayName: PostgreSQL Max Connections
+ description: PostgreSQL maximum number of database connections allowed.
+ value: '1000'
+- name: POSTGRESQL_SHARED_BUFFERS
+ displayName: PostgreSQL Shared Buffer Amount
+ description: Amount of memory dedicated for PostgreSQL shared memory buffers.
+ value: 1GB
+- name: ANSIBLE_SERVICE_NAME
+ displayName: Ansible Service Name
+ description: The name of the OpenShift Service exposed for the Ansible container.
+ value: ansible
+- name: ANSIBLE_ADMIN_PASSWORD
+ displayName: Ansible admin User password
+ required: true
+ description: The password for the Ansible container admin user
+ from: "[a-zA-Z0-9]{32}"
+ generate: expression
+- name: ANSIBLE_SECRET_KEY
+ displayName: Ansible Secret Key
+ required: true
+ description: Encryption key for the Ansible container
+ from: "[a-f0-9]{32}"
+ generate: expression
+- name: ANSIBLE_RABBITMQ_USER_NAME
+ displayName: RabbitMQ Username
+ required: true
+ description: Username for the Ansible RabbitMQ Server
+ value: ansible
+- name: ANSIBLE_RABBITMQ_PASSWORD
+ displayName: RabbitMQ Server Password
+ required: true
+ description: Password for the Ansible RabbitMQ Server
+ from: "[a-zA-Z0-9]{32}"
+ generate: expression
+- name: APPLICATION_CPU_REQ
+ displayName: Application Min CPU Requested
+ required: true
+ description: Minimum amount of CPU time the Application container will need (expressed in millicores).
+ value: 1000m
+- name: POSTGRESQL_CPU_REQ
+ displayName: PostgreSQL Min CPU Requested
+ required: true
+ description: Minimum amount of CPU time the PostgreSQL container will need (expressed in millicores).
+ value: 500m
+- name: MEMCACHED_CPU_REQ
+ displayName: Memcached Min CPU Requested
+ required: true
+ description: Minimum amount of CPU time the Memcached container will need (expressed in millicores).
+ value: 200m
+- name: ANSIBLE_CPU_REQ
+ displayName: Ansible Min CPU Requested
+ required: true
+ description: Minimum amount of CPU time the Ansible container will need (expressed in millicores).
+ value: 1000m
+- name: APPLICATION_MEM_REQ
+ displayName: Application Min RAM Requested
+ required: true
+ description: Minimum amount of memory the Application container will need.
+ value: 6144Mi
+- name: POSTGRESQL_MEM_REQ
+ displayName: PostgreSQL Min RAM Requested
+ required: true
+ description: Minimum amount of memory the PostgreSQL container will need.
+ value: 4Gi
+- name: MEMCACHED_MEM_REQ
+ displayName: Memcached Min RAM Requested
+ required: true
+ description: Minimum amount of memory the Memcached container will need.
+ value: 64Mi
+- name: ANSIBLE_MEM_REQ
+ displayName: Ansible Min RAM Requested
+ required: true
+ description: Minimum amount of memory the Ansible container will need.
+ value: 2048Mi
+- name: APPLICATION_MEM_LIMIT
+ displayName: Application Max RAM Limit
+ required: true
+ description: Maximum amount of memory the Application container can consume.
+ value: 16384Mi
+- name: POSTGRESQL_MEM_LIMIT
+ displayName: PostgreSQL Max RAM Limit
+ required: true
+ description: Maximum amount of memory the PostgreSQL container can consume.
+ value: 8Gi
+- name: MEMCACHED_MEM_LIMIT
+ displayName: Memcached Max RAM Limit
+ required: true
+ description: Maximum amount of memory the Memcached container can consume.
+ value: 256Mi
+- name: ANSIBLE_MEM_LIMIT
+ displayName: Ansible Max RAM Limit
+ required: true
+ description: Maximum amount of memory the Ansible container can consume.
+ value: 8096Mi
+- name: POSTGRESQL_IMG_NAME
+ displayName: PostgreSQL Image Name
+ description: This is the PostgreSQL image name requested to deploy.
+ value: registry.access.redhat.com/cloudforms46-beta/cfme-openshift-postgresql
+- name: POSTGRESQL_IMG_TAG
+ displayName: PostgreSQL Image Tag
+ description: This is the PostgreSQL image tag/version requested to deploy.
+ value: latest
+- name: MEMCACHED_IMG_NAME
+ displayName: Memcached Image Name
+ description: This is the Memcached image name requested to deploy.
+ value: registry.access.redhat.com/cloudforms46-beta/cfme-openshift-memcached
+- name: MEMCACHED_IMG_TAG
+ displayName: Memcached Image Tag
+ description: This is the Memcached image tag/version requested to deploy.
+ value: latest
+- name: FRONTEND_APPLICATION_IMG_NAME
+ displayName: Frontend Application Image Name
+ description: This is the Frontend Application image name requested to deploy.
+ value: registry.access.redhat.com/cloudforms46-beta/cfme-openshift-app-ui
+- name: BACKEND_APPLICATION_IMG_NAME
+ displayName: Backend Application Image Name
+ description: This is the Backend Application image name requested to deploy.
+ value: registry.access.redhat.com/cloudforms46-beta/cfme-openshift-app
+- name: FRONTEND_APPLICATION_IMG_TAG
+ displayName: Front end Application Image Tag
+ description: This is the CloudForms Frontend Application image tag/version requested to deploy.
+ value: latest
+- name: BACKEND_APPLICATION_IMG_TAG
+ displayName: Back end Application Image Tag
+ description: This is the CloudForms Backend Application image tag/version requested to deploy.
+ value: latest
+- name: ANSIBLE_IMG_NAME
+ displayName: Ansible Image Name
+ description: This is the Ansible image name requested to deploy.
+ value: registry.access.redhat.com/cloudforms46-beta/cfme-openshift-embedded-ansible
+- name: ANSIBLE_IMG_TAG
+ displayName: Ansible Image Tag
+ description: This is the Ansible image tag/version requested to deploy.
+ value: latest
+- name: APPLICATION_DOMAIN
+ displayName: Application Hostname
+ description: The exposed hostname that will route to the application service, if left blank a value will be defaulted.
+ value: ''
+- name: APPLICATION_REPLICA_COUNT
+ displayName: Application Replica Count
+ description: This is the number of Application replicas requested to deploy.
+ value: '1'
+- name: APPLICATION_INIT_DELAY
+ displayName: Application Init Delay
+ required: true
+ description: Delay in seconds before we attempt to initialize the application.
+ value: '15'
+- name: APPLICATION_VOLUME_CAPACITY
+ displayName: Application Volume Capacity
+ required: true
+ description: Volume space available for application data.
+ value: 5Gi
+- name: DATABASE_VOLUME_CAPACITY
+ displayName: Database Volume Capacity
+ required: true
+ description: Volume space available for database.
+ value: 15Gi
+- name: HTTPD_SERVICE_NAME
+ required: true
+ displayName: Apache httpd Service Name
+ description: The name of the OpenShift Service exposed for the httpd container.
+ value: httpd
+- name: HTTPD_DBUS_API_SERVICE_NAME
+ required: true
+ displayName: Apache httpd DBus API Service Name
+ description: The name of httpd dbus api service.
+ value: httpd-dbus-api
+- name: HTTPD_IMG_NAME
+ displayName: Apache httpd Image Name
+ description: This is the httpd image name requested to deploy.
+ value: registry.access.redhat.com/cloudforms46-beta/cfme-openshift-httpd
+- name: HTTPD_IMG_TAG
+ displayName: Apache httpd Image Tag
+ description: This is the httpd image tag/version requested to deploy.
+ value: latest
+- name: HTTPD_CONFIG_DIR
+ displayName: Apache Configuration Directory
+ description: Directory used to store the Apache configuration files.
+ value: "/etc/httpd/conf.d"
+- name: HTTPD_AUTH_CONFIG_DIR
+ displayName: External Authentication Configuration Directory
+ description: Directory used to store the external authentication configuration files.
+ value: "/etc/httpd/auth-conf.d"
+- name: HTTPD_CPU_REQ
+ displayName: Apache httpd Min CPU Requested
+ required: true
+ description: Minimum amount of CPU time the httpd container will need (expressed in millicores).
+ value: 500m
+- name: HTTPD_MEM_REQ
+ displayName: Apache httpd Min RAM Requested
+ required: true
+ description: Minimum amount of memory the httpd container will need.
+ value: 512Mi
+- name: HTTPD_MEM_LIMIT
+ displayName: Apache httpd Max RAM Limit
+ required: true
+ description: Maximum amount of memory the httpd container can consume.
+ value: 8192Mi
diff --git a/roles/openshift_examples/meta/main.yml b/roles/openshift_examples/meta/main.yml
index 1a34c85fc..9f46a4683 100644
--- a/roles/openshift_examples/meta/main.yml
+++ b/roles/openshift_examples/meta/main.yml
@@ -13,3 +13,4 @@ galaxy_info:
- cloud
dependencies:
- role: lib_utils
+- role: openshift_facts
diff --git a/roles/openshift_excluder/tasks/verify_excluder.yml b/roles/openshift_excluder/tasks/verify_excluder.yml
index 4f5277fa2..22a3fcd3b 100644
--- a/roles/openshift_excluder/tasks/verify_excluder.yml
+++ b/roles/openshift_excluder/tasks/verify_excluder.yml
@@ -3,7 +3,7 @@
# - excluder
- name: Get available excluder version
repoquery:
- name: "{{ excluder }}"
+ name: "{{ excluder }}{{ '-' ~ r_openshift_excluder_upgrade_target.split('.')[0:2] | join('.') ~ '*' if r_openshift_excluder_upgrade_target is defined else '' }}"
ignore_excluders: true
register: repoquery_out
diff --git a/roles/openshift_expand_partition/tasks/main.yml b/roles/openshift_expand_partition/tasks/main.yml
index 5ae863871..b38ebdfb4 100644
--- a/roles/openshift_expand_partition/tasks/main.yml
+++ b/roles/openshift_expand_partition/tasks/main.yml
@@ -8,7 +8,7 @@
- name: Determine if growpart is installed
command: "rpm -q cloud-utils-growpart"
register: has_growpart
- failed_when: has_growpart.cr != 0 and 'package cloud-utils-growpart is not installed' not in has_growpart.stdout
+ failed_when: has_growpart.rc != 0 and 'package cloud-utils-growpart is not installed' not in has_growpart.stdout
changed_when: false
when: openshift_is_containerized | bool
diff --git a/roles/openshift_facts/library/openshift_facts.py b/roles/openshift_facts/library/openshift_facts.py
index d7c358a2f..26f0525e9 100755
--- a/roles/openshift_facts/library/openshift_facts.py
+++ b/roles/openshift_facts/library/openshift_facts.py
@@ -1465,6 +1465,11 @@ class OpenShiftFacts(object):
if metadata:
metadata['project']['attributes'].pop('sshKeys', None)
metadata['instance'].pop('serviceAccounts', None)
+ elif bios_vendor == 'Amazon EC2':
+ # Adds support for Amazon EC2 C5 instance types
+ provider = 'aws'
+ metadata_url = 'http://169.254.169.254/latest/meta-data/'
+ metadata = get_provider_metadata(metadata_url)
elif virt_type == 'xen' and virt_role == 'guest' and re.match(r'.*\.amazon$', product_version):
provider = 'aws'
metadata_url = 'http://169.254.169.254/latest/meta-data/'
diff --git a/roles/openshift_gcp/files/bootstrap-script.sh b/roles/openshift_gcp/files/bootstrap-script.sh
new file mode 100644
index 000000000..0c3f1999b
--- /dev/null
+++ b/roles/openshift_gcp/files/bootstrap-script.sh
@@ -0,0 +1,42 @@
+#!/bin/bash
+#
+# This script is a startup script for bootstrapping a GCP node
+# from a config stored in the project metadata. It loops until
+# it finds the script and then starts the origin-node service.
+# TODO: generalize
+
+set -o errexit
+set -o nounset
+set -o pipefail
+
+if [[ "$( curl "http://metadata.google.internal/computeMetadata/v1/instance/attributes/bootstrap" -H "Metadata-Flavor: Google" )" != "true" ]]; then
+ echo "info: Bootstrap is not enabled for this instance, skipping" 1>&2
+ exit 0
+fi
+
+if ! id=$( curl "http://metadata.google.internal/computeMetadata/v1/instance/attributes/cluster-id" -H "Metadata-Flavor: Google" ); then
+ echo "error: Unable to get cluster-id for instance from cluster metadata" 1>&2
+ exit 1
+fi
+
+if ! node_group=$( curl "http://metadata.google.internal/computeMetadata/v1/instance/attributes/node-group" -H "Metadata-Flavor: Google" ); then
+ echo "error: Unable to get node-group for instance from cluster metadata" 1>&2
+ exit 1
+fi
+
+if ! config=$( curl -f "http://metadata.google.internal/computeMetadata/v1/instance/attributes/bootstrap-config" -H "Metadata-Flavor: Google" 2>/dev/null ); then
+ while true; do
+ if config=$( curl -f "http://metadata.google.internal/computeMetadata/v1/project/attributes/${id}-bootstrap-config" -H "Metadata-Flavor: Google" 2>/dev/null ); then
+ break
+ fi
+ echo "info: waiting for ${id}-bootstrap-config to become available in cluster metadata ..." 1>&2
+ sleep 5
+ done
+fi
+
+echo "Got bootstrap config from metadata"
+mkdir -p /etc/origin/node
+echo -n "${config}" > /etc/origin/node/bootstrap.kubeconfig
+echo "BOOTSTRAP_CONFIG_NAME=node-config-${node_group}" >> /etc/sysconfig/origin-node
+systemctl enable origin-node
+systemctl start origin-node
diff --git a/roles/openshift_gcp/files/openshift-bootstrap-update.service b/roles/openshift_gcp/files/openshift-bootstrap-update.service
new file mode 100644
index 000000000..c65b1b34e
--- /dev/null
+++ b/roles/openshift_gcp/files/openshift-bootstrap-update.service
@@ -0,0 +1,7 @@
+[Unit]
+Description=Update the OpenShift node bootstrap configuration
+
+[Service]
+Type=oneshot
+ExecStart=/usr/bin/openshift-bootstrap-update
+User=root
diff --git a/roles/openshift_gcp/files/openshift-bootstrap-update.timer b/roles/openshift_gcp/files/openshift-bootstrap-update.timer
new file mode 100644
index 000000000..1a517b33e
--- /dev/null
+++ b/roles/openshift_gcp/files/openshift-bootstrap-update.timer
@@ -0,0 +1,10 @@
+[Unit]
+Description=Update the OpenShift node bootstrap credentials hourly
+
+[Timer]
+OnBootSec=30s
+OnCalendar=hourly
+Persistent=true
+
+[Install]
+WantedBy=timers.target \ No newline at end of file
diff --git a/roles/openshift_gcp_image_prep/files/partition.conf b/roles/openshift_gcp/files/partition.conf
index b87e5e0b6..76e65ab9c 100644
--- a/roles/openshift_gcp_image_prep/files/partition.conf
+++ b/roles/openshift_gcp/files/partition.conf
@@ -1,3 +1,3 @@
[Service]
ExecStartPost=-/usr/bin/growpart /dev/sda 1
-ExecStartPost=-/sbin/xfs_growfs /
+ExecStartPost=-/sbin/xfs_growfs / \ No newline at end of file
diff --git a/roles/openshift_gcp/meta/main.yml b/roles/openshift_gcp/meta/main.yml
new file mode 100644
index 000000000..5e428f8de
--- /dev/null
+++ b/roles/openshift_gcp/meta/main.yml
@@ -0,0 +1,17 @@
+---
+galaxy_info:
+ author: Clayton Coleman
+ description:
+ company: Red Hat, Inc.
+ license: Apache License, Version 2.0
+ min_ansible_version: 1.8
+ platforms:
+ - name: EL
+ versions:
+ - 7
+ categories:
+ - cloud
+ - system
+dependencies:
+- role: lib_utils
+- role: lib_openshift
diff --git a/roles/openshift_gcp/tasks/add_custom_repositories.yml b/roles/openshift_gcp/tasks/add_custom_repositories.yml
new file mode 100644
index 000000000..04718f78e
--- /dev/null
+++ b/roles/openshift_gcp/tasks/add_custom_repositories.yml
@@ -0,0 +1,20 @@
+---
+- name: Copy custom repository secrets
+ copy:
+ src: "{{ files_dir }}/{{ item.1.sslclientcert }}"
+ dest: /var/lib/yum/custom_secret_{{ item.0 }}_cert
+ when: item.1.sslclientcert | default(false)
+ with_indexed_items: "{{ provision_custom_repositories }}"
+- name: Copy custom repository secrets
+ copy:
+ src: "{{ files_dir }}/{{ item.1.sslclientkey }}"
+ dest: /var/lib/yum/custom_secret_{{ item.0 }}_key
+ when: item.1.sslclientkey | default(false)
+ with_indexed_items: "{{ provision_custom_repositories }}"
+
+- name: Create any custom repos that are defined
+ template:
+ src: yum_repo.j2
+ dest: /etc/yum.repos.d/provision_custom_repositories.repo
+ when: provision_custom_repositories | length > 0
+ notify: refresh cache
diff --git a/roles/openshift_gcp_image_prep/tasks/main.yaml b/roles/openshift_gcp/tasks/configure_gcp_base_image.yml
index fee5ab618..2c6e2790a 100644
--- a/roles/openshift_gcp_image_prep/tasks/main.yaml
+++ b/roles/openshift_gcp/tasks/configure_gcp_base_image.yml
@@ -1,18 +1,10 @@
----
# GCE instances are starting with xfs AND barrier=1, which is only for extfs.
+---
- name: Remove barrier=1 from XFS fstab entries
- lineinfile:
- path: /etc/fstab
- regexp: '^(.+)xfs(.+?),?barrier=1,?(.*?)$'
- line: '\1xfs\2 \4'
- backrefs: yes
+ command: sed -i -e 's/xfs\(.*\)barrier=1/xfs\1/g; s/, / /g' /etc/fstab
- name: Ensure the root filesystem has XFS group quota turned on
- lineinfile:
- path: /boot/grub2/grub.cfg
- regexp: '^(.*)linux16 (.*)$'
- line: '\1linux16 \2 rootflags=gquota'
- backrefs: yes
+ command: sed -i -e 's/linux16 \(.*\)$/linux16 \1 rootflags=gquota/g' /boot/grub2/grub.cfg
- name: Ensure the root partition grows on startup
copy: src=partition.conf dest=/etc/systemd/system/google-instance-setup.service.d/
diff --git a/roles/openshift_gcp/tasks/configure_master_bootstrap.yml b/roles/openshift_gcp/tasks/configure_master_bootstrap.yml
new file mode 100644
index 000000000..591cb593c
--- /dev/null
+++ b/roles/openshift_gcp/tasks/configure_master_bootstrap.yml
@@ -0,0 +1,36 @@
+#
+# These tasks configure the instance to periodically update the project metadata with the
+# latest bootstrap kubeconfig from the project metadata. This keeps the project metadata
+# in sync with the cluster's configuration. We then invoke a CSR approve on any nodes that
+# are waiting to join the cluster.
+#
+---
+- name: Copy unit service
+ copy:
+ src: openshift-bootstrap-update.timer
+ dest: /etc/systemd/system/openshift-bootstrap-update.timer
+ owner: root
+ group: root
+ mode: 0664
+
+- name: Copy unit timer
+ copy:
+ src: openshift-bootstrap-update.service
+ dest: /etc/systemd/system/openshift-bootstrap-update.service
+ owner: root
+ group: root
+ mode: 0664
+
+- name: Create bootstrap update script
+ template: src=openshift-bootstrap-update.j2 dest=/usr/bin/openshift-bootstrap-update mode=u+rx
+
+- name: Start bootstrap update timer
+ systemd:
+ name: "openshift-bootstrap-update.timer"
+ state: started
+
+- name: Bootstrap all nodes that were identified with bootstrap metadata
+ run_once: true
+ oc_adm_csr:
+ nodes: "{{ groups['all'] | map('extract', hostvars) | selectattr('gce_metadata.bootstrap', 'match', 'true') | map(attribute='gce_name') | list }}"
+ timeout: 60
diff --git a/roles/openshift_gcp/tasks/configure_master_healthcheck.yml b/roles/openshift_gcp/tasks/configure_master_healthcheck.yml
new file mode 100644
index 000000000..aa9655977
--- /dev/null
+++ b/roles/openshift_gcp/tasks/configure_master_healthcheck.yml
@@ -0,0 +1,19 @@
+---
+- name: refresh yum cache
+ command: yum clean all
+ args:
+ warn: no
+ when: ansible_os_family == "RedHat"
+
+- name: install haproxy
+ package: name=haproxy state=present
+ register: result
+ until: '"failed" not in result'
+ retries: 10
+ delay: 10
+
+- name: configure haproxy
+ template: src=master_healthcheck.j2 dest=/etc/haproxy/haproxy.cfg
+
+- name: start and enable haproxy service
+ service: name=haproxy state=started enabled=yes
diff --git a/roles/openshift_gcp/tasks/dynamic_inventory.yml b/roles/openshift_gcp/tasks/dynamic_inventory.yml
new file mode 100644
index 000000000..1637da945
--- /dev/null
+++ b/roles/openshift_gcp/tasks/dynamic_inventory.yml
@@ -0,0 +1,5 @@
+---
+- name: Extract PEM from service account file
+ copy: content="{{ (lookup('file', openshift_gcp_iam_service_account_keyfile ) | from_json ).private_key }}" dest=/tmp/gce.pem mode=0600
+- name: Templatize environment script
+ template: src=inventory.j2.sh dest=/tmp/inventory.sh mode=u+rx
diff --git a/roles/openshift_gcp/tasks/frequent_log_rotation.yml b/roles/openshift_gcp/tasks/frequent_log_rotation.yml
new file mode 100644
index 000000000..0b4b27f84
--- /dev/null
+++ b/roles/openshift_gcp/tasks/frequent_log_rotation.yml
@@ -0,0 +1,18 @@
+---
+- name: Rotate logs daily
+ replace:
+ dest: /etc/logrotate.conf
+ regexp: '^weekly|monthly|yearly$'
+ replace: daily
+- name: Rotate at a smaller size of log
+ lineinfile:
+ dest: /etc/logrotate.conf
+ state: present
+ regexp: '^size'
+ line: size 10M
+- name: Limit total size of log files
+ lineinfile:
+ dest: /etc/logrotate.conf
+ state: present
+ regexp: '^maxsize'
+ line: maxsize 20M
diff --git a/roles/openshift_gcp/tasks/main.yaml b/roles/openshift_gcp/tasks/main.yml
index ad205ba33..fb147bc78 100644
--- a/roles/openshift_gcp/tasks/main.yaml
+++ b/roles/openshift_gcp/tasks/main.yml
@@ -17,7 +17,7 @@
- name: Provision GCP DNS domain
command: /tmp/openshift_gcp_provision_dns.sh
args:
- chdir: "{{ playbook_dir }}/files"
+ chdir: "{{ files_dir }}"
register: dns_provision
when:
- state | default('present') == 'present'
@@ -33,7 +33,7 @@
- name: Provision GCP resources
command: /tmp/openshift_gcp_provision.sh
args:
- chdir: "{{ playbook_dir }}/files"
+ chdir: "{{ files_dir }}"
when:
- state | default('present') == 'present'
diff --git a/roles/openshift_gcp/tasks/node_cloud_config.yml b/roles/openshift_gcp/tasks/node_cloud_config.yml
new file mode 100644
index 000000000..4e982f497
--- /dev/null
+++ b/roles/openshift_gcp/tasks/node_cloud_config.yml
@@ -0,0 +1,12 @@
+---
+- name: ensure the /etc/origin folder exists
+ file: name=/etc/origin state=directory
+
+- name: configure gce cloud config options
+ ini_file: dest=/etc/origin/cloudprovider/gce.conf section=Global option={{ item.key }} value={{ item.value }} state=present create=yes
+ with_items:
+ - { key: 'project-id', value: '{{ openshift_gcp_project }}' }
+ - { key: 'network-name', value: '{{ openshift_gcp_network_name }}' }
+ - { key: 'node-tags', value: '{{ openshift_gcp_prefix }}ocp' }
+ - { key: 'node-instance-prefix', value: '{{ openshift_gcp_prefix }}' }
+ - { key: 'multizone', value: 'false' }
diff --git a/roles/openshift_gcp/tasks/publish_image.yml b/roles/openshift_gcp/tasks/publish_image.yml
new file mode 100644
index 000000000..db8a7ca69
--- /dev/null
+++ b/roles/openshift_gcp/tasks/publish_image.yml
@@ -0,0 +1,32 @@
+---
+- name: Require openshift_gcp_image
+ fail:
+ msg: "A source image name or family is required for image publishing. Please ensure `openshift_gcp_image` is defined."
+ when: openshift_gcp_image is undefined
+
+- name: Require openshift_gcp_target_image
+ fail:
+ msg: "A target image name or family is required for image publishing. Please ensure `openshift_gcp_target_image` is defined."
+ when: openshift_gcp_target_image is undefined
+
+- block:
+ - name: Retrieve images in the {{ openshift_gcp_target_image }} family
+ command: >
+ gcloud --project "{{ openshift_gcp_project }}" compute images list
+ "--filter=family={{ openshift_gcp_target_image }}"
+ --format=json --sort-by ~creationTimestamp
+ register: images
+ - name: Prune oldest images
+ command: >
+ gcloud --project "{{ openshift_gcp_project }}" compute images delete "{{ item['name'] }}"
+ with_items: "{{ (images.stdout | default('[]') | from_json )[( openshift_gcp_keep_images | int ):] }}"
+ when: openshift_gcp_keep_images is defined
+
+- name: Copy the latest image in the family {{ openshift_gcp_image }} to {{ openshift_gcp_target_image }}
+ command: >
+ gcloud --project "{{ openshift_gcp_target_project | default(openshift_gcp_project) }}"
+ beta compute images create
+ "{{ openshift_gcp_target_image_name | default(openshift_gcp_target_image + '-' + lookup('pipe','date +%Y%m%d-%H%M%S')) }}"
+ --family "{{ openshift_gcp_target_image }}"
+ --source-image-family "{{ openshift_gcp_image }}"
+ --source-image-project "{{ openshift_gcp_project }}"
diff --git a/roles/openshift_gcp/tasks/setup_scale_group_facts.yml b/roles/openshift_gcp/tasks/setup_scale_group_facts.yml
new file mode 100644
index 000000000..0fda43123
--- /dev/null
+++ b/roles/openshift_gcp/tasks/setup_scale_group_facts.yml
@@ -0,0 +1,44 @@
+---
+- name: Add masters to requisite groups
+ add_host:
+ name: "{{ hostvars[item].gce_name }}"
+ groups: masters, etcd
+ with_items: "{{ groups['tag_ocp-master'] }}"
+
+- name: Add a master to the primary masters group
+ add_host:
+ name: "{{ hostvars[item].gce_name }}"
+ groups: primary_master
+ with_items: "{{ groups['tag_ocp-master'].0 }}"
+
+- name: Add non-bootstrapping master node instances to node group
+ add_host:
+ name: "{{ hostvars[item].gce_name }}"
+ groups: nodes
+ openshift_node_labels:
+ role: infra
+ with_items: "{{ groups['tag_ocp-master'] | default([]) | difference(groups['tag_ocp-bootstrap'] | default([])) }}"
+
+- name: Add infra node instances to node group
+ add_host:
+ name: "{{ hostvars[item].gce_name }}"
+ groups: nodes
+ openshift_node_labels:
+ role: infra
+ with_items: "{{ groups['tag_ocp-infra-node'] | default([]) | difference(groups['tag_ocp-bootstrap'] | default([])) }}"
+
+- name: Add node instances to node group
+ add_host:
+ name: "{{ hostvars[item].gce_name }}"
+ groups: nodes
+ openshift_node_labels:
+ role: app
+ with_items: "{{ groups['tag_ocp-node'] | default([]) | difference(groups['tag_ocp-bootstrap'] | default([])) }}"
+
+- name: Add bootstrap node instances
+ add_host:
+ name: "{{ hostvars[item].gce_name }}"
+ groups: bootstrap_nodes
+ openshift_node_bootstrap: True
+ with_items: "{{ groups['tag_ocp-node'] | default([]) | intersect(groups['tag_ocp-bootstrap'] | default([])) }}"
+ when: not (openshift_node_bootstrap | default(False))
diff --git a/roles/openshift_gcp/templates/inventory.j2.sh b/roles/openshift_gcp/templates/inventory.j2.sh
new file mode 100644
index 000000000..dcaffb578
--- /dev/null
+++ b/roles/openshift_gcp/templates/inventory.j2.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+export GCE_PROJECT="{{ openshift_gcp_project }}"
+export GCE_ZONE="{{ openshift_gcp_zone }}"
+export GCE_EMAIL="{{ (lookup('file', openshift_gcp_iam_service_account_keyfile ) | from_json ).client_email }}"
+export GCE_PEM_FILE_PATH="/tmp/gce.pem"
+export INVENTORY_IP_TYPE="{{ inventory_ip_type }}"
+export GCE_TAGGED_INSTANCES="{{ openshift_gcp_prefix }}ocp" \ No newline at end of file
diff --git a/roles/openshift_gcp/templates/master_healthcheck.j2 b/roles/openshift_gcp/templates/master_healthcheck.j2
new file mode 100644
index 000000000..189e578c5
--- /dev/null
+++ b/roles/openshift_gcp/templates/master_healthcheck.j2
@@ -0,0 +1,68 @@
+#---------------------------------------------------------------------
+# Example configuration for a possible web application. See the
+# full configuration options online.
+#
+# http://haproxy.1wt.eu/download/1.4/doc/configuration.txt
+#
+#---------------------------------------------------------------------
+
+#---------------------------------------------------------------------
+# Global settings
+#---------------------------------------------------------------------
+global
+ # to have these messages end up in /var/log/haproxy.log you will
+ # need to:
+ #
+ # 1) configure syslog to accept network log events. This is done
+ # by adding the '-r' option to the SYSLOGD_OPTIONS in
+ # /etc/sysconfig/syslog
+ #
+ # 2) configure local2 events to go to the /var/log/haproxy.log
+ # file. A line like the following can be added to
+ # /etc/sysconfig/syslog
+ #
+ # local2.* /var/log/haproxy.log
+ #
+ log 127.0.0.1 local2
+
+ chroot /var/lib/haproxy
+ pidfile /var/run/haproxy.pid
+ maxconn 4000
+ user haproxy
+ group haproxy
+ daemon
+
+ # turn on stats unix socket
+ stats socket /var/lib/haproxy/stats
+
+#---------------------------------------------------------------------
+# common defaults that all the 'listen' and 'backend' sections will
+# use if not designated in their block
+#---------------------------------------------------------------------
+defaults
+ mode http
+ log global
+ option httplog
+ option dontlognull
+ option http-server-close
+ option forwardfor except 127.0.0.0/8
+ option redispatch
+ retries 3
+ timeout http-request 10s
+ timeout queue 1m
+ timeout connect 10s
+ timeout client 1m
+ timeout server 1m
+ timeout http-keep-alive 10s
+ timeout check 10s
+ maxconn 3000
+
+#---------------------------------------------------------------------
+# main frontend which proxys to the backends
+#---------------------------------------------------------------------
+frontend http-proxy *:8080
+ acl url_healthz path_beg -i /healthz
+ use_backend ocp if url_healthz
+
+backend ocp
+ server ocp localhost:{{ internal_console_port }} ssl verify none
diff --git a/roles/openshift_gcp/templates/openshift-bootstrap-update.j2 b/roles/openshift_gcp/templates/openshift-bootstrap-update.j2
new file mode 100644
index 000000000..5b0563724
--- /dev/null
+++ b/roles/openshift_gcp/templates/openshift-bootstrap-update.j2
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+set -euo pipefail
+
+oc serviceaccounts create-kubeconfig -n openshift-infra node-bootstrapper > /root/bootstrap.kubeconfig
+gcloud compute project-info --project '{{ openshift_gcp_project }}' add-metadata --metadata-from-file '{{ openshift_gcp_prefix + openshift_gcp_clusterid | default("default") }}-bootstrap-config=/root/bootstrap.kubeconfig'
+rm -f /root/bootstrap.kubeconfig
diff --git a/roles/openshift_gcp/templates/provision.j2.sh b/roles/openshift_gcp/templates/provision.j2.sh
index 4d150bc74..794985322 100644
--- a/roles/openshift_gcp/templates/provision.j2.sh
+++ b/roles/openshift_gcp/templates/provision.j2.sh
@@ -9,15 +9,26 @@ if [[ -n "{{ openshift_gcp_ssh_private_key }}" ]]; then
ssh-add "{{ openshift_gcp_ssh_private_key }}" || true
fi
- # Check if the ~/.ssh/google_compute_engine.pub key is in the project metadata, and if not, add it there
- pub_key=$(cut -d ' ' -f 2 < "{{ openshift_gcp_ssh_private_key }}.pub")
+ # Check if the public key is in the project metadata, and if not, add it there
+ if [ -f "{{ openshift_gcp_ssh_private_key }}.pub" ]; then
+ pub_file="{{ openshift_gcp_ssh_private_key }}.pub"
+ pub_key=$(cut -d ' ' -f 2 < "{{ openshift_gcp_ssh_private_key }}.pub")
+ else
+ keyfile="${HOME}/.ssh/google_compute_engine"
+ pub_file="${keyfile}.pub"
+ mkdir -p "${HOME}/.ssh"
+ cp "{{ openshift_gcp_ssh_private_key }}" "${keyfile}"
+ chmod 0600 "${keyfile}"
+ ssh-keygen -y -f "${keyfile}" > "${pub_file}"
+ pub_key=$(cut -d ' ' -f 2 < "${pub_file}")
+ fi
key_tmp_file='/tmp/ocp-gce-keys'
if ! gcloud --project "{{ openshift_gcp_project }}" compute project-info describe | grep -q "$pub_key"; then
if gcloud --project "{{ openshift_gcp_project }}" compute project-info describe | grep -q ssh-rsa; then
gcloud --project "{{ openshift_gcp_project }}" compute project-info describe | grep ssh-rsa | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' -e 's/value: //' > "$key_tmp_file"
fi
echo -n 'cloud-user:' >> "$key_tmp_file"
- cat "{{ openshift_gcp_ssh_private_key }}.pub" >> "$key_tmp_file"
+ cat "${pub_file}" >> "$key_tmp_file"
gcloud --project "{{ openshift_gcp_project }}" compute project-info add-metadata --metadata-from-file "sshKeys=${key_tmp_file}"
rm -f "$key_tmp_file"
fi
diff --git a/roles/openshift_gcp/templates/yum_repo.j2 b/roles/openshift_gcp/templates/yum_repo.j2
new file mode 100644
index 000000000..77919ea75
--- /dev/null
+++ b/roles/openshift_gcp/templates/yum_repo.j2
@@ -0,0 +1,20 @@
+{% for repo in provision_custom_repositories %}
+[{{ repo.id | default(repo.name) }}]
+name={{ repo.name | default(repo.id) }}
+baseurl={{ repo.baseurl }}
+{% set enable_repo = repo.enabled | default(1) %}
+enabled={{ 1 if ( enable_repo == 1 or enable_repo == True ) else 0 }}
+{% set enable_gpg_check = repo.gpgcheck | default(1) %}
+gpgcheck={{ 1 if ( enable_gpg_check == 1 or enable_gpg_check == True ) else 0 }}
+{% if 'sslclientcert' in repo %}
+sslclientcert={{ "/var/lib/yum/custom_secret_" + (loop.index-1)|string + "_cert" if repo.sslclientcert }}
+{% endif %}
+{% if 'sslclientkey' in repo %}
+sslclientkey={{ "/var/lib/yum/custom_secret_" + (loop.index-1)|string + "_key" if repo.sslclientkey }}
+{% endif %}
+{% for key, value in repo.iteritems() %}
+{% if key not in ['id', 'name', 'baseurl', 'enabled', 'gpgcheck', 'sslclientkey', 'sslclientcert'] and value is defined %}
+{{ key }}={{ value }}
+{% endif %}
+{% endfor %}
+{% endfor %}
diff --git a/roles/openshift_grafana/defaults/main.yml b/roles/openshift_grafana/defaults/main.yml
new file mode 100644
index 000000000..7fd7a085d
--- /dev/null
+++ b/roles/openshift_grafana/defaults/main.yml
@@ -0,0 +1,12 @@
+---
+gf_body_tmp:
+ name: grafana_name
+ type: prometheus
+ typeLogoUrl: ''
+ access: proxy
+ url: prometheus_url
+ basicAuth: false
+ withCredentials: false
+ jsonData:
+ tlsSkipVerify: true
+ token: satoken
diff --git a/roles/openshift_grafana/files/grafana-ocp-oauth.yml b/roles/openshift_grafana/files/grafana-ocp-oauth.yml
new file mode 100644
index 000000000..82fa89004
--- /dev/null
+++ b/roles/openshift_grafana/files/grafana-ocp-oauth.yml
@@ -0,0 +1,661 @@
+---
+kind: Template
+apiVersion: v1
+metadata:
+ name: grafana-ocp
+ annotations:
+ "openshift.io/display-name": Grafana ocp
+ description: |
+ Grafana server with patched Prometheus datasource.
+ iconClass: icon-cogs
+ tags: "metrics,monitoring,grafana,prometheus"
+parameters:
+- description: The location of the proxy image
+ name: IMAGE_GF
+ value: mrsiano/grafana-ocp:latest
+- description: The location of the proxy image
+ name: IMAGE_PROXY
+ value: openshift/oauth-proxy:v1.0.0
+- description: External URL for the grafana route
+ name: ROUTE_URL
+ value: ""
+- description: The namespace to instantiate heapster under. Defaults to 'grafana'.
+ name: NAMESPACE
+ value: grafana
+- description: The session secret for the proxy
+ name: SESSION_SECRET
+ generate: expression
+ from: "[a-zA-Z0-9]{43}"
+objects:
+- apiVersion: v1
+ kind: ServiceAccount
+ metadata:
+ name: grafana-ocp
+ namespace: "${NAMESPACE}"
+ annotations:
+ serviceaccounts.openshift.io/oauth-redirectreference.primary: '{"kind":"OAuthRedirectReference","apiVersion":"v1","reference":{"kind":"Route","name":"grafana-ocp"}}'
+- apiVersion: authorization.openshift.io/v1
+ kind: ClusterRoleBinding
+ metadata:
+ name: gf-cluster-reader
+ roleRef:
+ name: cluster-reader
+ subjects:
+ - kind: ServiceAccount
+ name: grafana-ocp
+ namespace: "${NAMESPACE}"
+- apiVersion: route.openshift.io/v1
+ kind: Route
+ metadata:
+ name: grafana-ocp
+ namespace: "${NAMESPACE}"
+ spec:
+ host: "${ROUTE_URL}"
+ to:
+ name: grafana-ocp
+ tls:
+ termination: Reencrypt
+- apiVersion: v1
+ kind: Service
+ metadata:
+ name: grafana-ocp
+ annotations:
+ prometheus.io/scrape: "true"
+ prometheus.io/scheme: https
+ service.alpha.openshift.io/serving-cert-secret-name: gf-tls
+ namespace: "${NAMESPACE}"
+ labels:
+ metrics-infra: grafana-ocp
+ name: grafana-ocp
+ spec:
+ ports:
+ - name: grafana-ocp
+ port: 443
+ protocol: TCP
+ targetPort: 8443
+ selector:
+ app: grafana-ocp
+- apiVersion: v1
+ kind: Secret
+ metadata:
+ name: gf-proxy
+ namespace: "${NAMESPACE}"
+ stringData:
+ session_secret: "${SESSION_SECRET}="
+# Deploy Prometheus behind an oauth proxy
+- apiVersion: extensions/v1beta1
+ kind: Deployment
+ metadata:
+ labels:
+ app: grafana-ocp
+ name: grafana-ocp
+ namespace: "${NAMESPACE}"
+ spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app: grafana-ocp
+ template:
+ metadata:
+ labels:
+ app: grafana-ocp
+ name: grafana-ocp-app
+ spec:
+ serviceAccountName: grafana-ocp
+ containers:
+ - name: oauth-proxy
+ image: ${IMAGE_PROXY}
+ imagePullPolicy: IfNotPresent
+ ports:
+ - containerPort: 8443
+ name: web
+ args:
+ - -https-address=:8443
+ - -http-address=
+ - -email-domain=*
+ - -client-id=system:serviceaccount:${NAMESPACE}:grafana-ocp
+ - -upstream=http://localhost:3000
+ - -provider=openshift
+# - '-openshift-delegate-urls={"/api/datasources": {"resource": "namespace", "verb": "get", "resourceName": "grafana-ocp", "namespace": "${NAMESPACE}"}}'
+ - '-openshift-sar={"namespace": "${NAMESPACE}", "verb": "list", "resource": "services"}'
+ - -tls-cert=/etc/tls/private/tls.crt
+ - -tls-key=/etc/tls/private/tls.key
+ - -client-secret-file=/var/run/secrets/kubernetes.io/serviceaccount/token
+ - -cookie-secret-file=/etc/proxy/secrets/session_secret
+ - -skip-auth-regex=^/metrics,/api/datasources,/api/dashboards
+ volumeMounts:
+ - mountPath: /etc/tls/private
+ name: gf-tls
+ - mountPath: /etc/proxy/secrets
+ name: secrets
+
+ - name: grafana-ocp
+ image: ${IMAGE_GF}
+ ports:
+ - name: grafana-http
+ containerPort: 3000
+ volumeMounts:
+ - mountPath: "/root/go/src/github.com/grafana/grafana/data"
+ name: gf-data
+ - mountPath: "/root/go/src/github.com/grafana/grafana/conf"
+ name: gfconfig
+ - mountPath: /etc/tls/private
+ name: gf-tls
+ - mountPath: /etc/proxy/secrets
+ name: secrets
+ command:
+ - "./bin/grafana-server"
+
+ volumes:
+ - name: gfconfig
+ configMap:
+ name: gf-config
+ - name: secrets
+ secret:
+ secretName: gf-proxy
+ - name: gf-tls
+ secret:
+ secretName: gf-tls
+ - emptyDir: {}
+ name: gf-data
+- apiVersion: v1
+ kind: ConfigMap
+ metadata:
+ name: gf-config
+ namespace: "${NAMESPACE}"
+ data:
+ defaults.ini: |-
+ ##################### Grafana Configuration Defaults #####################
+ #
+ # Do not modify this file in grafana installs
+ #
+
+ # possible values : production, development
+ app_mode = production
+
+ # instance name, defaults to HOSTNAME environment variable value or hostname if HOSTNAME var is empty
+ instance_name = ${HOSTNAME}
+
+ #################################### Paths ###############################
+ [paths]
+ # Path to where grafana can store temp files, sessions, and the sqlite3 db (if that is used)
+ #
+ data = data
+ #
+ # Directory where grafana can store logs
+ #
+ logs = data/log
+ #
+ # Directory where grafana will automatically scan and look for plugins
+ #
+ plugins = data/plugins
+
+ #################################### Server ##############################
+ [server]
+ # Protocol (http, https, socket)
+ protocol = http
+
+ # The ip address to bind to, empty will bind to all interfaces
+ http_addr =
+
+ # The http port to use
+ http_port = 3000
+
+ # The public facing domain name used to access grafana from a browser
+ domain = localhost
+
+ # Redirect to correct domain if host header does not match domain
+ # Prevents DNS rebinding attacks
+ enforce_domain = false
+
+ # The full public facing url
+ root_url = %(protocol)s://%(domain)s:%(http_port)s/
+
+ # Log web requests
+ router_logging = false
+
+ # the path relative working path
+ static_root_path = public
+
+ # enable gzip
+ enable_gzip = false
+
+ # https certs & key file
+ cert_file = /etc/tls/private/tls.crt
+ cert_key = /etc/tls/private/tls.key
+
+ # Unix socket path
+ socket = /tmp/grafana.sock
+
+ #################################### Database ############################
+ [database]
+ # You can configure the database connection by specifying type, host, name, user and password
+ # as separate properties or as on string using the url property.
+
+ # Either "mysql", "postgres" or "sqlite3", it's your choice
+ type = sqlite3
+ host = 127.0.0.1:3306
+ name = grafana
+ user = root
+ # If the password contains # or ; you have to wrap it with triple quotes. Ex """#password;"""
+ password =
+ # Use either URL or the previous fields to configure the database
+ # Example: mysql://user:secret@host:port/database
+ url =
+
+ # Max idle conn setting default is 2
+ max_idle_conn = 2
+
+ # Max conn setting default is 0 (mean not set)
+ max_open_conn =
+
+ # For "postgres", use either "disable", "require" or "verify-full"
+ # For "mysql", use either "true", "false", or "skip-verify".
+ ssl_mode = disable
+
+ ca_cert_path =
+ client_key_path =
+ client_cert_path =
+ server_cert_name =
+
+ # For "sqlite3" only, path relative to data_path setting
+ path = grafana.db
+
+ #################################### Session #############################
+ [session]
+ # Either "memory", "file", "redis", "mysql", "postgres", "memcache", default is "file"
+ provider = file
+
+ # Provider config options
+ # memory: not have any config yet
+ # file: session dir path, is relative to grafana data_path
+ # redis: config like redis server e.g. `addr=127.0.0.1:6379,pool_size=100,db=grafana`
+ # postgres: user=a password=b host=localhost port=5432 dbname=c sslmode=disable
+ # mysql: go-sql-driver/mysql dsn config string, examples:
+ # `user:password@tcp(127.0.0.1:3306)/database_name`
+ # `user:password@unix(/var/run/mysqld/mysqld.sock)/database_name`
+ # memcache: 127.0.0.1:11211
+
+
+ provider_config = sessions
+
+ # Session cookie name
+ cookie_name = grafana_sess
+
+ # If you use session in https only, default is false
+ cookie_secure = false
+
+ # Session life time, default is 86400
+ session_life_time = 86400
+ gc_interval_time = 86400
+
+ #################################### Data proxy ###########################
+ [dataproxy]
+
+ # This enables data proxy logging, default is false
+ logging = false
+
+ #################################### Analytics ###########################
+ [analytics]
+ # Server reporting, sends usage counters to stats.grafana.org every 24 hours.
+ # No ip addresses are being tracked, only simple counters to track
+ # running instances, dashboard and error counts. It is very helpful to us.
+ # Change this option to false to disable reporting.
+ reporting_enabled = true
+
+ # Set to false to disable all checks to https://grafana.com
+ # for new versions (grafana itself and plugins), check is used
+ # in some UI views to notify that grafana or plugin update exists
+ # This option does not cause any auto updates, nor send any information
+ # only a GET request to https://grafana.com to get latest versions
+ check_for_updates = true
+
+ # Google Analytics universal tracking code, only enabled if you specify an id here
+ google_analytics_ua_id =
+
+ # Google Tag Manager ID, only enabled if you specify an id here
+ google_tag_manager_id =
+
+ #################################### Security ############################
+ [security]
+ # default admin user, created on startup
+ admin_user = admin
+
+ # default admin password, can be changed before first start of grafana, or in profile settings
+ admin_password = admin
+
+ # used for signing
+ secret_key = SW2YcwTIb9zpOOhoPsMm
+
+ # Auto-login remember days
+ login_remember_days = 7
+ cookie_username = grafana_user
+ cookie_remember_name = grafana_remember
+
+ # disable gravatar profile images
+ disable_gravatar = false
+
+ # data source proxy whitelist (ip_or_domain:port separated by spaces)
+ data_source_proxy_whitelist =
+
+ [snapshots]
+ # snapshot sharing options
+ external_enabled = true
+ external_snapshot_url = https://snapshots-origin.raintank.io
+ external_snapshot_name = Publish to snapshot.raintank.io
+
+ # remove expired snapshot
+ snapshot_remove_expired = true
+
+ # remove snapshots after 90 days
+ snapshot_TTL_days = 90
+
+ #################################### Users ####################################
+ [users]
+ # disable user signup / registration
+ allow_sign_up = true
+
+ # Allow non admin users to create organizations
+ allow_org_create = true
+
+ # Set to true to automatically assign new users to the default organization (id 1)
+ auto_assign_org = true
+
+ # Default role new users will be automatically assigned (if auto_assign_org above is set to true)
+ auto_assign_org_role = Admin
+
+ # Require email validation before sign up completes
+ verify_email_enabled = false
+
+ # Background text for the user field on the login page
+ login_hint = email or username
+
+ # Default UI theme ("dark" or "light")
+ default_theme = dark
+
+ # External user management
+ external_manage_link_url =
+ external_manage_link_name =
+ external_manage_info =
+
+ [auth]
+ # Set to true to disable (hide) the login form, useful if you use OAuth
+ disable_login_form = true
+
+ # Set to true to disable the signout link in the side menu. useful if you use auth.proxy
+ disable_signout_menu = true
+
+ #################################### Anonymous Auth ######################
+ [auth.anonymous]
+ # enable anonymous access
+ enabled = true
+
+ # specify organization name that should be used for unauthenticated users
+ org_name = Main Org.
+
+ # specify role for unauthenticated users
+ org_role = Admin
+
+ #################################### Github Auth #########################
+ [auth.github]
+ enabled = false
+ allow_sign_up = true
+ client_id = some_id
+ client_secret = some_secret
+ scopes = user:email
+ auth_url = https://github.com/login/oauth/authorize
+ token_url = https://github.com/login/oauth/access_token
+ api_url = https://api.github.com/user
+ team_ids =
+ allowed_organizations =
+
+ #################################### Google Auth #########################
+ [auth.google]
+ enabled = false
+ allow_sign_up = true
+ client_id = some_client_id
+ client_secret = some_client_secret
+ scopes = https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email
+ auth_url = https://accounts.google.com/o/oauth2/auth
+ token_url = https://accounts.google.com/o/oauth2/token
+ api_url = https://www.googleapis.com/oauth2/v1/userinfo
+ allowed_domains =
+ hosted_domain =
+
+ #################################### Grafana.com Auth ####################
+ # legacy key names (so they work in env variables)
+ [auth.grafananet]
+ enabled = false
+ allow_sign_up = true
+ client_id = some_id
+ client_secret = some_secret
+ scopes = user:email
+ allowed_organizations =
+
+ [auth.grafana_com]
+ enabled = false
+ allow_sign_up = true
+ client_id = some_id
+ client_secret = some_secret
+ scopes = user:email
+ allowed_organizations =
+
+ #################################### Generic OAuth #######################
+ [auth.generic_oauth]
+ name = OAuth
+ enabled = false
+ allow_sign_up = true
+ client_id = some_id
+ client_secret = some_secret
+ scopes = user:email
+ auth_url =
+ token_url =
+ api_url =
+ team_ids =
+ allowed_organizations =
+
+ #################################### Basic Auth ##########################
+ [auth.basic]
+ enabled = false
+
+ #################################### Auth Proxy ##########################
+ [auth.proxy]
+ enabled = true
+ header_name = X-WEBAUTH-USER
+ header_property = username
+ auto_sign_up = true
+ ldap_sync_ttl = 60
+ whitelist =
+
+ #################################### Auth LDAP ###########################
+ [auth.ldap]
+ enabled = false
+ config_file = /etc/grafana/ldap.toml
+ allow_sign_up = true
+
+ #################################### SMTP / Emailing #####################
+ [smtp]
+ enabled = false
+ host = localhost:25
+ user =
+ # If the password contains # or ; you have to wrap it with trippel quotes. Ex """#password;"""
+ password =
+ cert_file =
+ key_file =
+ skip_verify = false
+ from_address = admin@grafana.localhost
+ from_name = Grafana
+ ehlo_identity =
+
+ [emails]
+ welcome_email_on_sign_up = false
+ templates_pattern = emails/*.html
+
+ #################################### Logging ##########################
+ [log]
+ # Either "console", "file", "syslog". Default is console and file
+ # Use space to separate multiple modes, e.g. "console file"
+ mode = console file
+
+ # Either "debug", "info", "warn", "error", "critical", default is "info"
+ level = error
+
+ # optional settings to set different levels for specific loggers. Ex filters = sqlstore:debug
+ filters =
+
+ # For "console" mode only
+ [log.console]
+ level =
+
+ # log line format, valid options are text, console and json
+ format = console
+
+ # For "file" mode only
+ [log.file]
+ level =
+
+ # log line format, valid options are text, console and json
+ format = text
+
+ # This enables automated log rotate(switch of following options), default is true
+ log_rotate = true
+
+ # Max line number of single file, default is 1000000
+ max_lines = 1000000
+
+ # Max size shift of single file, default is 28 means 1 << 28, 256MB
+ max_size_shift = 28
+
+ # Segment log daily, default is true
+ daily_rotate = true
+
+ # Expired days of log file(delete after max days), default is 7
+ max_days = 7
+
+ [log.syslog]
+ level =
+
+ # log line format, valid options are text, console and json
+ format = text
+
+ # Syslog network type and address. This can be udp, tcp, or unix. If left blank, the default unix endpoints will be used.
+ network =
+ address =
+
+ # Syslog facility. user, daemon and local0 through local7 are valid.
+ facility =
+
+ # Syslog tag. By default, the process' argv[0] is used.
+ tag =
+
+
+ #################################### AMQP Event Publisher ################
+ [event_publisher]
+ enabled = false
+ rabbitmq_url = amqp://localhost/
+ exchange = grafana_events
+
+ #################################### Dashboard JSON files ################
+ [dashboards.json]
+ enabled = false
+ path = /var/lib/grafana/dashboards
+
+ #################################### Usage Quotas ########################
+ [quota]
+ enabled = false
+
+ #### set quotas to -1 to make unlimited. ####
+ # limit number of users per Org.
+ org_user = 10
+
+ # limit number of dashboards per Org.
+ org_dashboard = 100
+
+ # limit number of data_sources per Org.
+ org_data_source = 10
+
+ # limit number of api_keys per Org.
+ org_api_key = 10
+
+ # limit number of orgs a user can create.
+ user_org = 10
+
+ # Global limit of users.
+ global_user = -1
+
+ # global limit of orgs.
+ global_org = -1
+
+ # global limit of dashboards
+ global_dashboard = -1
+
+ # global limit of api_keys
+ global_api_key = -1
+
+ # global limit on number of logged in users.
+ global_session = -1
+
+ #################################### Alerting ############################
+ [alerting]
+ # Disable alerting engine & UI features
+ enabled = true
+ # Makes it possible to turn off alert rule execution but alerting UI is visible
+ execute_alerts = true
+
+ #################################### Internal Grafana Metrics ############
+ # Metrics available at HTTP API Url /api/metrics
+ [metrics]
+ enabled = true
+ interval_seconds = 10
+
+ # Send internal Grafana metrics to graphite
+ [metrics.graphite]
+ # Enable by setting the address setting (ex localhost:2003)
+ address =
+ prefix = prod.grafana.%(instance_name)s.
+
+ [grafana_net]
+ url = https://grafana.com
+
+ [grafana_com]
+ url = https://grafana.com
+
+ #################################### Distributed tracing ############
+ [tracing.jaeger]
+ # jaeger destination (ex localhost:6831)
+ address =
+ # tag that will always be included in when creating new spans. ex (tag1:value1,tag2:value2)
+ always_included_tag =
+ # Type specifies the type of the sampler: const, probabilistic, rateLimiting, or remote
+ sampler_type = const
+ # jaeger samplerconfig param
+ # for "const" sampler, 0 or 1 for always false/true respectively
+ # for "probabilistic" sampler, a probability between 0 and 1
+ # for "rateLimiting" sampler, the number of spans per second
+ # for "remote" sampler, param is the same as for "probabilistic"
+ # and indicates the initial sampling rate before the actual one
+ # is received from the mothership
+ sampler_param = 1
+
+ #################################### External Image Storage ##############
+ [external_image_storage]
+ # You can choose between (s3, webdav, gcs)
+ provider =
+
+ [external_image_storage.s3]
+ bucket_url =
+ bucket =
+ region =
+ path =
+ access_key =
+ secret_key =
+
+ [external_image_storage.webdav]
+ url =
+ username =
+ password =
+ public_url =
+
+ [external_image_storage.gcs]
+ key_file =
+ bucket =
diff --git a/roles/openshift_grafana/files/grafana-ocp.yml b/roles/openshift_grafana/files/grafana-ocp.yml
new file mode 100644
index 000000000..bc7b4b286
--- /dev/null
+++ b/roles/openshift_grafana/files/grafana-ocp.yml
@@ -0,0 +1,76 @@
+---
+kind: Template
+apiVersion: v1
+metadata:
+ name: grafana-ocp
+ annotations:
+ "openshift.io/display-name": Grafana ocp
+ description: |
+ Grafana server with patched Prometheus datasource.
+ iconClass: icon-cogs
+ tags: "metrics,monitoring,grafana,prometheus"
+parameters:
+- description: External URL for the grafana route
+ name: ROUTE_URL
+ value: ""
+- description: The namespace to instantiate heapster under. Defaults to 'grafana'.
+ name: NAMESPACE
+ value: grafana
+objects:
+- apiVersion: route.openshift.io/v1
+ kind: Route
+ metadata:
+ name: grafana-ocp
+ namespace: "${NAMESPACE}"
+ spec:
+ host: "${ROUTE_URL}"
+ to:
+ name: grafana-ocp
+- apiVersion: v1
+ kind: Service
+ metadata:
+ name: grafana-ocp
+ namespace: "${NAMESPACE}"
+ labels:
+ metrics-infra: grafana-ocp
+ name: grafana-ocp
+ spec:
+ selector:
+ name: grafana-ocp
+ ports:
+ - port: 8082
+ protocol: TCP
+ targetPort: grafana-http
+- apiVersion: v1
+ kind: ReplicationController
+ metadata:
+ name: grafana-ocp
+ namespace: "${NAMESPACE}"
+ labels:
+ metrics-infra: grafana-ocp
+ name: grafana-ocp
+ spec:
+ selector:
+ name: grafana-ocp
+ replicas: 1
+ template:
+ version: v1
+ metadata:
+ labels:
+ metrics-infra: grafana-ocp
+ name: grafana-ocp
+ spec:
+ volumes:
+ - name: data
+ emptyDir: {}
+ containers:
+ - image: "mrsiano/grafana-ocp:latest"
+ name: grafana-ocp
+ ports:
+ - name: grafana-http
+ containerPort: 3000
+ volumeMounts:
+ - name: data
+ mountPath: "/root/go/src/github.com/grafana/grafana/data"
+ command:
+ - "./bin/grafana-server"
diff --git a/roles/openshift_grafana/files/openshift-cluster-monitoring.json b/roles/openshift_grafana/files/openshift-cluster-monitoring.json
new file mode 100644
index 000000000..f59ca997f
--- /dev/null
+++ b/roles/openshift_grafana/files/openshift-cluster-monitoring.json
@@ -0,0 +1,5138 @@
+{
+ "dashboard": {
+ "description": "Monitors Openshift cluster using Prometheus. Shows overall cluster CPU / Memory / Filesystem usage as well as individual pod, containers, systemd services statistics. Uses cAdvisor metrics only.",
+ "editable": true,
+ "gnetId": 315,
+ "graphTooltip": 0,
+ "hideControls": false,
+ "id": null,
+ "links": [],
+ "rows": [
+ {
+ "collapse": false,
+ "height": "200px",
+ "panels": [
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "decimals": 2,
+ "editable": true,
+ "error": false,
+ "fill": 1,
+ "grid": {},
+ "height": "200px",
+ "id": 32,
+ "legend": {
+ "alignAsTable": false,
+ "avg": true,
+ "current": true,
+ "max": false,
+ "min": false,
+ "rightSide": false,
+ "show": false,
+ "sideWidth": 200,
+ "sort": "current",
+ "sortDesc": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 2,
+ "links": [],
+ "nullPointMode": "connected",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 12,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum (irate (container_network_receive_bytes_total{kubernetes_io_hostname=~\"^$Node$\"}[2m]))",
+ "format": "time_series",
+ "instant": false,
+ "interval": "1s",
+ "intervalFactor": 1,
+ "legendFormat": "Received",
+ "metric": "network",
+ "refId": "A",
+ "step": 1
+ },
+ {
+ "expr": "- sum (irate (container_network_transmit_bytes_total{kubernetes_io_hostname=~\"^$Node$\"}[2m]))",
+ "format": "time_series",
+ "interval": "1s",
+ "intervalFactor": 1,
+ "legendFormat": "Sent",
+ "metric": "network",
+ "refId": "B",
+ "step": 1
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Network I/O pressure",
+ "tooltip": {
+ "msResolution": false,
+ "shared": true,
+ "sort": 0,
+ "value_type": "cumulative"
+ },
+ "transparent": false,
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "Bps",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "Bps",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": false,
+ "title": "Network I/O pressure",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": false,
+ "height": "250px",
+ "panels": [
+ {
+ "cacheTimeout": null,
+ "colorBackground": false,
+ "colorValue": true,
+ "colors": [
+ "rgba(50, 172, 45, 0.97)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(245, 54, 54, 0.9)"
+ ],
+ "datasource": "${DS_PR}",
+ "editable": true,
+ "error": false,
+ "format": "percent",
+ "gauge": {
+ "maxValue": 100,
+ "minValue": 0,
+ "show": true,
+ "thresholdLabels": false,
+ "thresholdMarkers": true
+ },
+ "height": "180px",
+ "id": 4,
+ "interval": null,
+ "links": [],
+ "mappingType": 1,
+ "mappingTypes": [
+ {
+ "name": "value to text",
+ "value": 1
+ },
+ {
+ "name": "range to text",
+ "value": 2
+ }
+ ],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": "",
+ "postfixFontSize": "50%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "rangeMaps": [
+ {
+ "from": "null",
+ "text": "N/A",
+ "to": "null"
+ }
+ ],
+ "span": 4,
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": false
+ },
+ "tableColumn": "",
+ "targets": [
+ {
+ "expr": "sum (container_memory_working_set_bytes{id=\"/\",kubernetes_io_hostname=~\"^$Node$\"}) / sum (machine_memory_bytes{kubernetes_io_hostname=~\"^$Node$\"}) * 100",
+ "format": "time_series",
+ "interval": "",
+ "intervalFactor": 1,
+ "refId": "A",
+ "step": 20
+ }
+ ],
+ "thresholds": "",
+ "title": "Cluster memory usage",
+ "transparent": false,
+ "type": "singlestat",
+ "valueFontSize": "80%",
+ "valueMaps": [
+ {
+ "op": "=",
+ "text": "N/A",
+ "value": "null"
+ }
+ ],
+ "valueName": "current"
+ },
+ {
+ "cacheTimeout": null,
+ "colorBackground": false,
+ "colorValue": true,
+ "colors": [
+ "rgba(50, 172, 45, 0.97)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(245, 54, 54, 0.9)"
+ ],
+ "datasource": "${DS_PR}",
+ "decimals": 2,
+ "editable": true,
+ "error": false,
+ "format": "percent",
+ "gauge": {
+ "maxValue": 100,
+ "minValue": 0,
+ "show": true,
+ "thresholdLabels": false,
+ "thresholdMarkers": true
+ },
+ "height": "180px",
+ "id": 6,
+ "interval": null,
+ "links": [],
+ "mappingType": 1,
+ "mappingTypes": [
+ {
+ "name": "value to text",
+ "value": 1
+ },
+ {
+ "name": "range to text",
+ "value": 2
+ }
+ ],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": "",
+ "postfixFontSize": "50%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "rangeMaps": [
+ {
+ "from": "null",
+ "text": "N/A",
+ "to": "null"
+ }
+ ],
+ "span": 4,
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": false
+ },
+ "tableColumn": "",
+ "targets": [
+ {
+ "expr": "sum (irate (container_cpu_usage_seconds_total{id=\"/\",kubernetes_io_hostname=~\"^$Node$\"}[2m])) / sum (machine_cpu_cores{kubernetes_io_hostname=~\"^$Node$\"}) * 100",
+ "format": "time_series",
+ "interval": "",
+ "intervalFactor": 1,
+ "refId": "A",
+ "step": 20
+ }
+ ],
+ "thresholds": "",
+ "title": "Cluster CPU usage ",
+ "type": "singlestat",
+ "valueFontSize": "80%",
+ "valueMaps": [
+ {
+ "op": "=",
+ "text": "N/A",
+ "value": "null"
+ }
+ ],
+ "valueName": "current"
+ },
+ {
+ "cacheTimeout": null,
+ "colorBackground": false,
+ "colorValue": true,
+ "colors": [
+ "rgba(50, 172, 45, 0.97)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(245, 54, 54, 0.9)"
+ ],
+ "datasource": "${DS_PR}",
+ "decimals": 2,
+ "editable": true,
+ "error": false,
+ "format": "percent",
+ "gauge": {
+ "maxValue": 100,
+ "minValue": 0,
+ "show": true,
+ "thresholdLabels": false,
+ "thresholdMarkers": true
+ },
+ "height": "180px",
+ "id": 7,
+ "interval": null,
+ "links": [],
+ "mappingType": 1,
+ "mappingTypes": [
+ {
+ "name": "value to text",
+ "value": 1
+ },
+ {
+ "name": "range to text",
+ "value": 2
+ }
+ ],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": "",
+ "postfixFontSize": "50%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "rangeMaps": [
+ {
+ "from": "null",
+ "text": "N/A",
+ "to": "null"
+ }
+ ],
+ "span": 4,
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": false
+ },
+ "tableColumn": "",
+ "targets": [
+ {
+ "expr": "sum (container_fs_usage_bytes{device=~\"^/dev/mapper/docker_.*\",id=\"/\",kubernetes_io_hostname=~\"^$Node$\"}) / sum (container_fs_limit_bytes{device=~\"^/dev/mapper/docker_.*\",id=\"/\",kubernetes_io_hostname=~\"^$Node$\"}) * 100",
+ "format": "time_series",
+ "hide": false,
+ "interval": "",
+ "intervalFactor": 1,
+ "legendFormat": "",
+ "metric": "",
+ "refId": "A",
+ "step": 20
+ }
+ ],
+ "thresholds": "",
+ "title": "Cluster filesystem usage",
+ "type": "singlestat",
+ "valueFontSize": "80%",
+ "valueMaps": [
+ {
+ "op": "=",
+ "text": "N/A",
+ "value": "null"
+ }
+ ],
+ "valueName": "current"
+ },
+ {
+ "cacheTimeout": null,
+ "colorBackground": false,
+ "colorValue": false,
+ "colors": [
+ "rgba(50, 172, 45, 0.97)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(245, 54, 54, 0.9)"
+ ],
+ "datasource": "${DS_PR}",
+ "decimals": 2,
+ "editable": true,
+ "error": false,
+ "format": "bytes",
+ "gauge": {
+ "maxValue": 100,
+ "minValue": 0,
+ "show": false,
+ "thresholdLabels": false,
+ "thresholdMarkers": true
+ },
+ "height": "1px",
+ "id": 9,
+ "interval": null,
+ "links": [],
+ "mappingType": 1,
+ "mappingTypes": [
+ {
+ "name": "value to text",
+ "value": 1
+ },
+ {
+ "name": "range to text",
+ "value": 2
+ }
+ ],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": "",
+ "postfixFontSize": "20%",
+ "prefix": "",
+ "prefixFontSize": "20%",
+ "rangeMaps": [
+ {
+ "from": "null",
+ "text": "N/A",
+ "to": "null"
+ }
+ ],
+ "span": 2,
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": false
+ },
+ "tableColumn": "",
+ "targets": [
+ {
+ "expr": "sum (container_memory_working_set_bytes{id=\"/\",kubernetes_io_hostname=~\"^$Node$\"})",
+ "format": "time_series",
+ "interval": "",
+ "intervalFactor": 1,
+ "refId": "A",
+ "step": 20
+ }
+ ],
+ "thresholds": "",
+ "title": "Used",
+ "type": "singlestat",
+ "valueFontSize": "50%",
+ "valueMaps": [
+ {
+ "op": "=",
+ "text": "N/A",
+ "value": "null"
+ }
+ ],
+ "valueName": "current"
+ },
+ {
+ "cacheTimeout": null,
+ "colorBackground": false,
+ "colorValue": false,
+ "colors": [
+ "rgba(50, 172, 45, 0.97)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(245, 54, 54, 0.9)"
+ ],
+ "datasource": "${DS_PR}",
+ "decimals": 2,
+ "editable": true,
+ "error": false,
+ "format": "bytes",
+ "gauge": {
+ "maxValue": 100,
+ "minValue": 0,
+ "show": false,
+ "thresholdLabels": false,
+ "thresholdMarkers": true
+ },
+ "height": "1px",
+ "id": 10,
+ "interval": null,
+ "links": [],
+ "mappingType": 1,
+ "mappingTypes": [
+ {
+ "name": "value to text",
+ "value": 1
+ },
+ {
+ "name": "range to text",
+ "value": 2
+ }
+ ],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": "",
+ "postfixFontSize": "50%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "rangeMaps": [
+ {
+ "from": "null",
+ "text": "N/A",
+ "to": "null"
+ }
+ ],
+ "span": 2,
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": false
+ },
+ "tableColumn": "",
+ "targets": [
+ {
+ "expr": "sum (machine_memory_bytes{kubernetes_io_hostname=~\"^$Node$\"})",
+ "format": "time_series",
+ "interval": "",
+ "intervalFactor": 1,
+ "refId": "A",
+ "step": 20
+ }
+ ],
+ "thresholds": "",
+ "title": "Total",
+ "type": "singlestat",
+ "valueFontSize": "50%",
+ "valueMaps": [
+ {
+ "op": "=",
+ "text": "N/A",
+ "value": "null"
+ }
+ ],
+ "valueName": "current"
+ },
+ {
+ "cacheTimeout": null,
+ "colorBackground": false,
+ "colorValue": false,
+ "colors": [
+ "rgba(50, 172, 45, 0.97)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(245, 54, 54, 0.9)"
+ ],
+ "datasource": "${DS_PR}",
+ "decimals": 2,
+ "editable": true,
+ "error": false,
+ "format": "none",
+ "gauge": {
+ "maxValue": 100,
+ "minValue": 0,
+ "show": false,
+ "thresholdLabels": false,
+ "thresholdMarkers": true
+ },
+ "height": "1px",
+ "id": 11,
+ "interval": null,
+ "links": [],
+ "mappingType": 1,
+ "mappingTypes": [
+ {
+ "name": "value to text",
+ "value": 1
+ },
+ {
+ "name": "range to text",
+ "value": 2
+ }
+ ],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": " cores",
+ "postfixFontSize": "30%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "rangeMaps": [
+ {
+ "from": "null",
+ "text": "N/A",
+ "to": "null"
+ }
+ ],
+ "span": 2,
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": false
+ },
+ "tableColumn": "",
+ "targets": [
+ {
+ "expr": "sum (irate (container_cpu_usage_seconds_total{id=\"/\",kubernetes_io_hostname=~\"^$Node$\"}[2m]))",
+ "format": "time_series",
+ "interval": "",
+ "intervalFactor": 1,
+ "refId": "A",
+ "step": 20
+ }
+ ],
+ "thresholds": "",
+ "title": "Used",
+ "type": "singlestat",
+ "valueFontSize": "50%",
+ "valueMaps": [
+ {
+ "op": "=",
+ "text": "N/A",
+ "value": "null"
+ }
+ ],
+ "valueName": "current"
+ },
+ {
+ "cacheTimeout": null,
+ "colorBackground": false,
+ "colorValue": false,
+ "colors": [
+ "rgba(50, 172, 45, 0.97)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(245, 54, 54, 0.9)"
+ ],
+ "datasource": "${DS_PR}",
+ "decimals": 2,
+ "editable": true,
+ "error": false,
+ "format": "none",
+ "gauge": {
+ "maxValue": 100,
+ "minValue": 0,
+ "show": false,
+ "thresholdLabels": false,
+ "thresholdMarkers": true
+ },
+ "height": "1px",
+ "id": 12,
+ "interval": null,
+ "links": [],
+ "mappingType": 1,
+ "mappingTypes": [
+ {
+ "name": "value to text",
+ "value": 1
+ },
+ {
+ "name": "range to text",
+ "value": 2
+ }
+ ],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": " cores",
+ "postfixFontSize": "30%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "rangeMaps": [
+ {
+ "from": "null",
+ "text": "N/A",
+ "to": "null"
+ }
+ ],
+ "span": 2,
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": false
+ },
+ "tableColumn": "",
+ "targets": [
+ {
+ "expr": "sum (machine_cpu_cores{kubernetes_io_hostname=~\"^$Node$\"})",
+ "format": "time_series",
+ "interval": "",
+ "intervalFactor": 1,
+ "refId": "A",
+ "step": 20
+ }
+ ],
+ "thresholds": "",
+ "title": "Total",
+ "type": "singlestat",
+ "valueFontSize": "50%",
+ "valueMaps": [
+ {
+ "op": "=",
+ "text": "N/A",
+ "value": "null"
+ }
+ ],
+ "valueName": "current"
+ },
+ {
+ "cacheTimeout": null,
+ "colorBackground": false,
+ "colorValue": false,
+ "colors": [
+ "rgba(50, 172, 45, 0.97)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(245, 54, 54, 0.9)"
+ ],
+ "datasource": "${DS_PR}",
+ "decimals": 2,
+ "editable": true,
+ "error": false,
+ "format": "bytes",
+ "gauge": {
+ "maxValue": 100,
+ "minValue": 0,
+ "show": false,
+ "thresholdLabels": false,
+ "thresholdMarkers": true
+ },
+ "height": "1px",
+ "id": 13,
+ "interval": null,
+ "links": [],
+ "mappingType": 1,
+ "mappingTypes": [
+ {
+ "name": "value to text",
+ "value": 1
+ },
+ {
+ "name": "range to text",
+ "value": 2
+ }
+ ],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": "",
+ "postfixFontSize": "50%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "rangeMaps": [
+ {
+ "from": "null",
+ "text": "N/A",
+ "to": "null"
+ }
+ ],
+ "span": 2,
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": false
+ },
+ "tableColumn": "",
+ "targets": [
+ {
+ "expr": "sum (container_fs_usage_bytes{device=~\"^/dev/mapper/docker_.*$\",id=\"/\",kubernetes_io_hostname=~\"^$Node$\"})",
+ "format": "time_series",
+ "interval": "",
+ "intervalFactor": 1,
+ "refId": "A",
+ "step": 20
+ }
+ ],
+ "thresholds": "",
+ "title": "Used",
+ "type": "singlestat",
+ "valueFontSize": "50%",
+ "valueMaps": [
+ {
+ "op": "=",
+ "text": "N/A",
+ "value": "null"
+ }
+ ],
+ "valueName": "current"
+ },
+ {
+ "cacheTimeout": null,
+ "colorBackground": false,
+ "colorValue": false,
+ "colors": [
+ "rgba(50, 172, 45, 0.97)",
+ "rgba(237, 129, 40, 0.89)",
+ "rgba(245, 54, 54, 0.9)"
+ ],
+ "datasource": "${DS_PR}",
+ "decimals": 2,
+ "editable": true,
+ "error": false,
+ "format": "bytes",
+ "gauge": {
+ "maxValue": 100,
+ "minValue": 0,
+ "show": false,
+ "thresholdLabels": false,
+ "thresholdMarkers": true
+ },
+ "height": "1px",
+ "id": 14,
+ "interval": null,
+ "links": [],
+ "mappingType": 1,
+ "mappingTypes": [
+ {
+ "name": "value to text",
+ "value": 1
+ },
+ {
+ "name": "range to text",
+ "value": 2
+ }
+ ],
+ "maxDataPoints": 100,
+ "nullPointMode": "connected",
+ "nullText": null,
+ "postfix": "",
+ "postfixFontSize": "50%",
+ "prefix": "",
+ "prefixFontSize": "50%",
+ "rangeMaps": [
+ {
+ "from": "null",
+ "text": "N/A",
+ "to": "null"
+ }
+ ],
+ "span": 2,
+ "sparkline": {
+ "fillColor": "rgba(31, 118, 189, 0.18)",
+ "full": false,
+ "lineColor": "rgb(31, 120, 193)",
+ "show": false
+ },
+ "tableColumn": "",
+ "targets": [
+ {
+ "expr": "sum (container_fs_limit_bytes{device=~\"^/dev/mapper/docker_.*$\",id=\"/\",kubernetes_io_hostname=~\"^$Node$\"})",
+ "format": "time_series",
+ "hide": false,
+ "interval": "",
+ "intervalFactor": 1,
+ "refId": "A",
+ "step": 20
+ }
+ ],
+ "thresholds": "",
+ "title": "Total",
+ "type": "singlestat",
+ "valueFontSize": "50%",
+ "valueMaps": [
+ {
+ "op": "=",
+ "text": "N/A",
+ "value": "null"
+ }
+ ],
+ "valueName": "current"
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": false,
+ "title": "Total usage",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": true,
+ "height": 250,
+ "panels": [
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "fill": 1,
+ "id": 33,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 12,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum (irate (container_cpu_usage_seconds_total{id=\"/\",kubernetes_io_hostname=~\"^$Node$\"}[2m])) / sum (machine_cpu_cores{kubernetes_io_hostname=~\"^$Node$\"}) ",
+ "format": "time_series",
+ "hide": false,
+ "interval": "1s",
+ "intervalFactor": 1,
+ "legendFormat": "overall cpu usage",
+ "refId": "A",
+ "step": 1
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Cluster CPU Usage",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "percent",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": false,
+ "title": "Dashboard Row",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": true,
+ "height": "250px",
+ "panels": [
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "decimals": 3,
+ "editable": true,
+ "error": false,
+ "fill": 0,
+ "grid": {},
+ "height": "",
+ "id": 17,
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": true,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "sort": "current",
+ "sortDesc": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "connected",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 12,
+ "stack": false,
+ "steppedLine": true,
+ "targets": [
+ {
+ "expr": "sum (irate (container_cpu_usage_seconds_total{image!=\"\",name=~\"^k8s_.*\",kubernetes_io_hostname=~\"^$Node$\"}[2m])) by (pod_name) * 100",
+ "format": "time_series",
+ "hide": false,
+ "interval": "",
+ "intervalFactor": 1,
+ "legendFormat": "{{ pod_name }}",
+ "metric": "container_cpu",
+ "refId": "A",
+ "step": 2
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Pods CPU usage ",
+ "tooltip": {
+ "msResolution": true,
+ "shared": true,
+ "sort": 2,
+ "value_type": "cumulative"
+ },
+ "transparent": false,
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "percent",
+ "label": "% Usage",
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": false,
+ "title": "Pods CPU usage",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": true,
+ "height": "250px",
+ "panels": [
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "decimals": 3,
+ "editable": true,
+ "error": false,
+ "fill": 0,
+ "grid": {},
+ "height": "",
+ "id": 24,
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": true,
+ "hideEmpty": false,
+ "hideZero": false,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "sideWidth": null,
+ "sort": "current",
+ "sortDesc": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 2,
+ "links": [],
+ "nullPointMode": "connected",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 12,
+ "stack": false,
+ "steppedLine": true,
+ "targets": [
+ {
+ "expr": "sum (irate (container_cpu_usage_seconds_total{image!=\"\",name=~\"^k8s_.*\",container_name!=\"POD\",kubernetes_io_hostname=~\"^$Node$\"}[2m])) by (container_name, pod_name)",
+ "format": "time_series",
+ "hide": false,
+ "interval": "1s",
+ "intervalFactor": 1,
+ "legendFormat": "pod: {{ pod_name }} | {{ container_name }}",
+ "metric": "container_cpu",
+ "refId": "A",
+ "step": 2
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Containers Cores Usage",
+ "tooltip": {
+ "msResolution": true,
+ "shared": true,
+ "sort": 2,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "none",
+ "label": "cores",
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": false,
+ "title": "Containers CPU usage",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": true,
+ "height": "250px",
+ "panels": [
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "decimals": 3,
+ "editable": true,
+ "error": false,
+ "fill": 0,
+ "grid": {},
+ "height": "",
+ "id": 23,
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": true,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "sort": "current",
+ "sortDesc": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 2,
+ "links": [],
+ "nullPointMode": "connected",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 12,
+ "stack": false,
+ "steppedLine": true,
+ "targets": [
+ {
+ "expr": "sum (irate (container_cpu_usage_seconds_total{id!=\"/\",kubernetes_io_hostname=~\"^$Node$\"}[2m])) by (id)",
+ "format": "time_series",
+ "hide": false,
+ "interval": "1s",
+ "intervalFactor": 1,
+ "legendFormat": "{{ id }}",
+ "metric": "container_cpu",
+ "refId": "A",
+ "step": 2
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "System services CPU usage ",
+ "tooltip": {
+ "msResolution": true,
+ "shared": true,
+ "sort": 2,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "none",
+ "label": "cores",
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": false,
+ "title": "System services CPU usage",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": true,
+ "height": 411,
+ "panels": [
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "decimals": 3,
+ "editable": true,
+ "error": false,
+ "fill": 0,
+ "grid": {},
+ "id": 34,
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": true,
+ "max": false,
+ "min": false,
+ "rightSide": false,
+ "show": true,
+ "sort": "current",
+ "sortDesc": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 2,
+ "links": [],
+ "nullPointMode": "connected",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 12,
+ "stack": false,
+ "steppedLine": true,
+ "targets": [
+ {
+ "expr": "sum (irate (container_memory_usage_bytes{id!=\"/\",kubernetes_io_hostname=~\"^$Node$\"}[2m])) by (id)",
+ "format": "time_series",
+ "hide": false,
+ "interval": "1s",
+ "intervalFactor": 1,
+ "legendFormat": "{{ id }}",
+ "metric": "container_cpu",
+ "refId": "A",
+ "step": 2
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "All processes Memory usage ",
+ "tooltip": {
+ "msResolution": true,
+ "shared": true,
+ "sort": 2,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "bytes",
+ "label": "cores",
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": false,
+ "title": "All processes CPU usage",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": true,
+ "height": "250px",
+ "panels": [
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "decimals": 2,
+ "editable": true,
+ "error": false,
+ "fill": 0,
+ "grid": {},
+ "id": 25,
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": true,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "sideWidth": 200,
+ "sort": "current",
+ "sortDesc": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 2,
+ "links": [],
+ "nullPointMode": "connected",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 12,
+ "stack": false,
+ "steppedLine": true,
+ "targets": [
+ {
+ "expr": "sum (container_memory_working_set_bytes{image!=\"\",name=~\"^k8s_.*\",kubernetes_io_hostname=~\"^$Node$\"}) by (pod_name)",
+ "format": "time_series",
+ "interval": "1s",
+ "intervalFactor": 1,
+ "legendFormat": "{{ pod_name }}",
+ "metric": "container_memory_usage:sort_desc",
+ "refId": "A",
+ "step": 10
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Pods memory usage",
+ "tooltip": {
+ "msResolution": false,
+ "shared": true,
+ "sort": 2,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "bytes",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": false,
+ "title": "Pods memory usage",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": true,
+ "height": "250px",
+ "panels": [
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "decimals": 2,
+ "editable": true,
+ "error": false,
+ "fill": 0,
+ "grid": {},
+ "id": 26,
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": true,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "sideWidth": 200,
+ "sort": "current",
+ "sortDesc": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 2,
+ "links": [],
+ "nullPointMode": "connected",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 12,
+ "stack": false,
+ "steppedLine": true,
+ "targets": [
+ {
+ "expr": "sum (container_memory_rss{systemd_service_name=\"\",kubernetes_io_hostname=~\"^$Node$\"}) by (systemd_service_name)",
+ "format": "time_series",
+ "hide": false,
+ "interval": "1s",
+ "intervalFactor": 1,
+ "legendFormat": "{{ systemd_service_name }}",
+ "metric": "container_memory_usage:sort_desc",
+ "refId": "B",
+ "step": 2
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "System services memory usage",
+ "tooltip": {
+ "msResolution": false,
+ "shared": true,
+ "sort": 2,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "bytes",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": false,
+ "title": "System services memory usage",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": true,
+ "height": "250px",
+ "panels": [
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "decimals": 2,
+ "editable": true,
+ "error": false,
+ "fill": 0,
+ "grid": {},
+ "id": 27,
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": true,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "sideWidth": 200,
+ "sort": "current",
+ "sortDesc": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 2,
+ "links": [],
+ "nullPointMode": "connected",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 12,
+ "stack": false,
+ "steppedLine": true,
+ "targets": [
+ {
+ "expr": "sum (container_memory_working_set_bytes{image!=\"\",name=~\"^k8s_.*\",container_name!=\"POD\",kubernetes_io_hostname=~\"^$Node$\"}) by (container_name, pod_name)",
+ "format": "time_series",
+ "interval": "1s",
+ "intervalFactor": 1,
+ "legendFormat": "pod: {{ pod_name }} | {{ container_name }}",
+ "metric": "container_memory_usage:sort_desc",
+ "refId": "A",
+ "step": 10
+ },
+ {
+ "expr": "sum (container_memory_working_set_bytes{image!=\"\",name!~\"^k8s_.*\",kubernetes_io_hostname=~\"^$Node$\"}) by (kubernetes_io_hostname, name, image)",
+ "format": "time_series",
+ "hide": false,
+ "interval": "1s",
+ "intervalFactor": 1,
+ "legendFormat": "docker: {{ kubernetes_io_hostname }} | {{ image }} ({{ name }})",
+ "metric": "container_memory_usage:sort_desc",
+ "refId": "B",
+ "step": 10
+ },
+ {
+ "expr": "sum (container_memory_working_set_bytes{rkt_container_name!=\"\",kubernetes_io_hostname=~\"^$Node$\"}) by (kubernetes_io_hostname, rkt_container_name)",
+ "format": "time_series",
+ "hide": false,
+ "interval": "1s",
+ "intervalFactor": 1,
+ "legendFormat": "rkt: {{ kubernetes_io_hostname }} | {{ rkt_container_name }}",
+ "metric": "container_memory_usage:sort_desc",
+ "refId": "C",
+ "step": 10
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Containers memory usage",
+ "tooltip": {
+ "msResolution": false,
+ "shared": true,
+ "sort": 2,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "bytes",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": false,
+ "title": "Containers memory usage",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": true,
+ "height": "500px",
+ "panels": [
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "decimals": 2,
+ "editable": true,
+ "error": false,
+ "fill": 0,
+ "grid": {},
+ "id": 28,
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": true,
+ "max": false,
+ "min": false,
+ "rightSide": false,
+ "show": true,
+ "sideWidth": 200,
+ "sort": "current",
+ "sortDesc": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 2,
+ "links": [],
+ "nullPointMode": "connected",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 12,
+ "stack": false,
+ "steppedLine": true,
+ "targets": [
+ {
+ "expr": "sum (container_memory_working_set_bytes{id!=\"/\",kubernetes_io_hostname=~\"^$Node$\"}) by (id)",
+ "interval": "1s",
+ "intervalFactor": 1,
+ "legendFormat": "{{ id }}",
+ "metric": "container_memory_usage:sort_desc",
+ "refId": "A",
+ "step": 1
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "All processes memory usage",
+ "tooltip": {
+ "msResolution": false,
+ "shared": true,
+ "sort": 2,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "bytes",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": false,
+ "title": "All processes memory usage",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": true,
+ "height": "250px",
+ "panels": [
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "decimals": 2,
+ "editable": true,
+ "error": false,
+ "fill": 1,
+ "grid": {},
+ "id": 30,
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": true,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "sideWidth": 200,
+ "sort": "current",
+ "sortDesc": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 2,
+ "links": [],
+ "nullPointMode": "connected",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 12,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum (irate (container_network_receive_bytes_total{image!=\"\",name=~\"^k8s_.*\",kubernetes_io_hostname=~\"^$Node$\"}[2m])) by (container_name, pod_name)",
+ "format": "time_series",
+ "hide": false,
+ "interval": "1s",
+ "intervalFactor": 1,
+ "legendFormat": "-> pod: {{ pod_name }} | {{ container_name }}",
+ "metric": "network",
+ "refId": "B",
+ "step": 1
+ },
+ {
+ "expr": "- sum (irate (container_network_transmit_bytes_total{image!=\"\",name=~\"^k8s_.*\",kubernetes_io_hostname=~\"^$Node$\"}[2m])) by (container_name, pod_name)",
+ "format": "time_series",
+ "hide": false,
+ "interval": "1s",
+ "intervalFactor": 1,
+ "legendFormat": "<- pod: {{ pod_name }} | {{ container_name }}",
+ "metric": "network",
+ "refId": "D",
+ "step": 1
+ },
+ {
+ "expr": "sum (irate (container_network_receive_bytes_total{image!=\"\",name!~\"^k8s_.*\",kubernetes_io_hostname=~\"^$Node$\"}[2m])) by (kubernetes_io_hostname, name, image)",
+ "format": "time_series",
+ "hide": false,
+ "interval": "1s",
+ "intervalFactor": 1,
+ "legendFormat": "-> docker: {{ kubernetes_io_hostname }} | {{ image }} ({{ name }})",
+ "metric": "network",
+ "refId": "A",
+ "step": 1
+ },
+ {
+ "expr": "- sum (irate (container_network_transmit_bytes_total{image!=\"\",name!~\"^k8s_.*\",kubernetes_io_hostname=~\"^$Node$\"}[2m])) by (kubernetes_io_hostname, name, image)",
+ "format": "time_series",
+ "hide": false,
+ "interval": "1s",
+ "intervalFactor": 1,
+ "legendFormat": "<- docker: {{ kubernetes_io_hostname }} | {{ image }} ({{ name }})",
+ "metric": "network",
+ "refId": "C",
+ "step": 1
+ },
+ {
+ "expr": "sum (irate (container_network_transmit_bytes_total{rkt_container_name!=\"\",kubernetes_io_hostname=~\"^$Node$\"}[2m])) by (kubernetes_io_hostname, rkt_container_name)",
+ "format": "time_series",
+ "hide": false,
+ "interval": "1s",
+ "intervalFactor": 1,
+ "legendFormat": "-> rkt: {{ kubernetes_io_hostname }} | {{ rkt_container_name }}",
+ "metric": "network",
+ "refId": "E",
+ "step": 1
+ },
+ {
+ "expr": "- sum (irate (container_network_transmit_bytes_total{rkt_container_name!=\"\",kubernetes_io_hostname=~\"^$Node$\"}[2m])) by (kubernetes_io_hostname, rkt_container_name)",
+ "format": "time_series",
+ "hide": false,
+ "interval": "1s",
+ "intervalFactor": 1,
+ "legendFormat": "<- rkt: {{ kubernetes_io_hostname }} | {{ rkt_container_name }}",
+ "metric": "network",
+ "refId": "F",
+ "step": 1
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Containers network I/O ",
+ "tooltip": {
+ "msResolution": false,
+ "shared": true,
+ "sort": 2,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "Bps",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": false,
+ "title": "Containers network I/O",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": true,
+ "height": 277,
+ "panels": [
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "decimals": 2,
+ "editable": true,
+ "error": false,
+ "fill": 1,
+ "grid": {},
+ "id": 16,
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": true,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "sideWidth": 200,
+ "sort": "current",
+ "sortDesc": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 2,
+ "links": [],
+ "nullPointMode": "connected",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 12,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum (irate (container_network_receive_bytes_total{image!=\"\",name=~\"^k8s_.*\",kubernetes_io_hostname=~\"^$Node$\"}[2m])) by (pod_name)",
+ "format": "time_series",
+ "interval": "1s",
+ "intervalFactor": 1,
+ "legendFormat": "-> {{ pod_name }}",
+ "metric": "network",
+ "refId": "A",
+ "step": 1
+ },
+ {
+ "expr": "- sum (irate (container_network_transmit_bytes_total{image!=\"\",name=~\"^k8s_.*\",kubernetes_io_hostname=~\"^$Node$\"}[2m])) by (pod_name)",
+ "format": "time_series",
+ "interval": "1s",
+ "intervalFactor": 1,
+ "legendFormat": "<- {{ pod_name }}",
+ "metric": "network",
+ "refId": "B",
+ "step": 1
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Pods network I/O ",
+ "tooltip": {
+ "msResolution": false,
+ "shared": true,
+ "sort": 2,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "Bps",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": false,
+ "title": "Pods network I/O",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": true,
+ "height": "500px",
+ "panels": [
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "decimals": 2,
+ "editable": true,
+ "error": false,
+ "fill": 1,
+ "grid": {},
+ "id": 29,
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": true,
+ "max": false,
+ "min": false,
+ "rightSide": false,
+ "show": true,
+ "sideWidth": 200,
+ "sort": "current",
+ "sortDesc": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 2,
+ "links": [],
+ "nullPointMode": "connected",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 12,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum (irate (container_network_receive_bytes_total{id!=\"/\",kubernetes_io_hostname=~\"^$Node$\"}[2m])) by (id)",
+ "format": "time_series",
+ "instant": true,
+ "interval": "1s",
+ "intervalFactor": 1,
+ "legendFormat": "-> {{ id }}",
+ "metric": "network",
+ "refId": "A",
+ "step": 1
+ },
+ {
+ "expr": "- sum (irate (container_network_transmit_bytes_total{id!=\"/\",kubernetes_io_hostname=~\"^$Node$\"}[2m])) by (id)",
+ "format": "time_series",
+ "interval": "1s",
+ "intervalFactor": 1,
+ "legendFormat": "<- {{ id }}",
+ "metric": "network",
+ "refId": "B",
+ "step": 1
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "All processes network I/O ",
+ "tooltip": {
+ "msResolution": false,
+ "shared": true,
+ "sort": 2,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "Bps",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": false,
+ "title": "All processes network I/O",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": true,
+ "height": 250,
+ "panels": [
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "fill": 1,
+ "id": 35,
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": true,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "sort": "avg",
+ "sortDesc": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 12,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(openshift_build_total) by (phase,reason)",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{ phase }} | {{ reason }}",
+ "refId": "A",
+ "step": 1
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "openshift_build_total",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "fill": 1,
+ "id": 54,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "count(openshift_build_active_time_seconds{phase=\"running\"} offset 10m)",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "refId": "A",
+ "step": 2
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Returns the number of builds that have been running for more than 10 minutes (600 seconds).",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "fill": 1,
+ "id": 55,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "count(openshift_build_active_time_seconds{phase=\"pending\"} offset 10m)",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "refId": "A",
+ "step": 2
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Returns the number of build that have been waiting at least 10 minutes (600 seconds) to start.",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "fill": 1,
+ "id": 56,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(openshift_build_total{phase=\"Failed\"})",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "refId": "A",
+ "step": 2
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Returns the number of failed builds, regardless of the failure reason.",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "fill": 1,
+ "id": 57,
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": true,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "openshift_build_total{phase=\"Failed\",reason=\"FetchSourceFailed\"}",
+ "format": "time_series",
+ "intervalFactor": 1,
+ "legendFormat": "{{ instance }}",
+ "refId": "A",
+ "step": 1
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Returns the number of failed builds because of problems retrieving source from the associated Git repository.",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": true,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "fill": 1,
+ "id": 58,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": false,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(openshift_build_total{phase=\"Complete\"})",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "refId": "A",
+ "step": 2
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Returns the number of successfully completed builds.",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "fill": 0,
+ "id": 59,
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": true,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "sort": "avg",
+ "sortDesc": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "percentage": false,
+ "pointradius": 1,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "openshift_build_total{phase=\"Failed\"} offset 5m",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{ reason }}",
+ "refId": "A",
+ "step": 2
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Returns the failed builds totals, per failure reason, from 5 minutes ago.",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "OpenShift Builds",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": true,
+ "height": 250,
+ "panels": [
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "fill": 1,
+ "id": 36,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(openshift_sdn_pod_setup_latency_sum)",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "refId": "A",
+ "step": 1
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "openshift_sdn_pod_setup_latency_sum",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "fill": 1,
+ "id": 41,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(openshift_sdn_pod_teardown_latency{quantile=\"0.9\"}) by (instance)",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "refId": "A",
+ "step": 1
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "openshift_sdn_pod_teardown_latency",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "fill": 1,
+ "id": 50,
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": true,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "sort": "avg",
+ "sortDesc": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "topk(10, (sum by (pod_name) (irate(container_network_receive_bytes_total{pod_name!=\"\"}[5m]))))",
+ "format": "time_series",
+ "interval": "",
+ "intervalFactor": 1,
+ "legendFormat": "{{ pod_name }}",
+ "refId": "A",
+ "step": 1
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Top 10 pods doing the most receive network traffic",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "decbytes",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "fill": 1,
+ "id": 37,
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": true,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "sort": "avg",
+ "sortDesc": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "openshift_sdn_pod_ips",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{ instance }} | {{ role }}",
+ "refId": "A",
+ "step": 1
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "openshift_sdn_pod_ips",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "fill": 1,
+ "id": 39,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "garbage_collector_monitoring_route:openshift:io_v1_rate_limiter_use",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "refId": "A",
+ "step": 1
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "garbage_collector_monitoring_route:openshift:io_v1_rate_limiter_use",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "fill": 1,
+ "id": 42,
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": true,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "sort": "avg",
+ "sortDesc": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "openshift_sdn_arp_cache_entries",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{ role }} | {{ instance }}",
+ "refId": "A",
+ "step": 1
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "openshift_sdn_arp_cache_entries",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "fill": 1,
+ "id": 40,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "openshift_sdn_arp_cache_entries",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "refId": "A",
+ "step": 1
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "openshift_sdn_arp_cache_entries",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "OpenShift SDN",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": true,
+ "height": 250,
+ "panels": [
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "fill": 1,
+ "id": 44,
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": true,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "sort": "avg",
+ "sortDesc": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "irate(kubelet_pleg_relist_latency_microseconds{kubernetes_io_hostname=~\"$Node\",quantile=\"0.9\"}[2m])",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{ role }} | {{ instance }}",
+ "refId": "A",
+ "step": 4
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "kubelet_pleg_relist",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "µs",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "fill": 1,
+ "id": 51,
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": true,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "sort": "avg",
+ "sortDesc": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "irate(kubelet_docker_operations_latency_microseconds{quantile=\"0.9\"}[2m])",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{ operation_type }}",
+ "refId": "A",
+ "step": 4
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "kubelet_docker_operations_latency_microseconds{quantile=\"0.9\"}",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "µs",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "fill": 1,
+ "id": 52,
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": true,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "sort": "avg",
+ "sortDesc": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "kubelet_docker_operations_timeout",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{ operation_type }}",
+ "refId": "A",
+ "step": 4
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Returns a running count (not a rate) of docker operations that have timed out since the kubelet was started.",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "none",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "fill": 1,
+ "id": 53,
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": true,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "sort": "avg",
+ "sortDesc": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "kubelet_docker_operations_errors",
+ "format": "time_series",
+ "intervalFactor": 1,
+ "legendFormat": "{{ operation_type }}",
+ "refId": "A",
+ "step": 2
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Returns a running count (not a rate) of docker operations that have failed since the kubelet was started.",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "none",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "Kubelet",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": true,
+ "height": 250,
+ "panels": [
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "fill": 1,
+ "id": 46,
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": true,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "sort": "avg",
+ "sortDesc": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "irate(scrape_samples_scraped[2m])",
+ "format": "time_series",
+ "hide": false,
+ "intervalFactor": 2,
+ "legendFormat": "{{ kubernetes_name }} | {{ instance }} ",
+ "refId": "A",
+ "step": 4
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "scrape_samples_scraped",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "none",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "fill": 1,
+ "id": 68,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sort_desc(sum without (cpu) (irate(container_cpu_usage_seconds_total{container_name=\"prometheus\"}[5m])))",
+ "format": "time_series",
+ "interval": "1s",
+ "intervalFactor": 1,
+ "refId": "A",
+ "step": 2
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "CPU per instance of Prometheus container.",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "none",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "Prometheus",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": true,
+ "height": 250,
+ "panels": [
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "fill": 1,
+ "id": 48,
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": true,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "sort": "avg",
+ "sortDesc": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sort_desc(sum without (instance,type,client,contentType) (irate(apiserver_request_count{verb!~\"GET|LIST|WATCH\"}[2m]))) > 0",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{ resource }} || {{ verb }}",
+ "refId": "A",
+ "step": 4
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Number of mutating API requests being made to the control plane.",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "none",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "fill": 1,
+ "id": 49,
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": true,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "sort": "avg",
+ "sortDesc": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sort_desc(sum without (instance,type,client,contentType) (irate(apiserver_request_count{verb=~\"GET|LIST|WATCH\"}[2m]))) > 0",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{ resource }} || {{ pod }}",
+ "refId": "A",
+ "step": 4
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Number of non-mutating API requests being made to the control plane.",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "none",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "fill": 1,
+ "id": 74,
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": true,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "endpoint_queue_latency",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": " quantile {{ quantile }}",
+ "refId": "A",
+ "step": 4
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "endpoint_queue_latency",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "ms",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "API Server",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": true,
+ "height": 250,
+ "panels": [
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "fill": 1,
+ "id": 61,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "etcd_disk_wal_fsync_duration_seconds_count",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "refId": "A",
+ "step": 10
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "etcd_disk_wal_fsync_duration_seconds_count",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "none",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "etcd",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": true,
+ "height": 250,
+ "panels": [
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "fill": 1,
+ "id": 62,
+ "legend": {
+ "alignAsTable": false,
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "rightSide": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 12,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(changes(container_start_time_seconds[10m]))",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "refId": "A",
+ "step": 2
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "The number of containers that start or restart over the last ten minutes.",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "none",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "Changes in your cluster",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": true,
+ "height": 250,
+ "panels": [
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "fill": 1,
+ "id": 63,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(machine_cpu_cores)",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "refId": "A",
+ "step": 4
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Total number of cores in the cluster.",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "none",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "fill": 1,
+ "id": 64,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(sort_desc(irate(container_cpu_usage_seconds_total{id=\"/\"}[5m])))",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "refId": "A",
+ "step": 4
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Total number of consumed cores.",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "none",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "fill": 1,
+ "id": 65,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sort_desc(sum by (kubernetes_io_hostname,type) (irate(container_cpu_usage_seconds_total{id=\"/\"}[5m])))",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "refId": "A",
+ "step": 4
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "CPU consumed per node in the cluster.",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "none",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "fill": 1,
+ "id": 66,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sort_desc(sum by (cpu,id,pod_name,container_name) (irate(container_cpu_usage_seconds_total{role=\"infra\"}[5m])))",
+ "format": "time_series",
+ "hide": false,
+ "intervalFactor": 2,
+ "refId": "A",
+ "step": 4
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "CPU consumption per system service or container on the infrastructure nodes.",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "none",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "fill": 1,
+ "id": 67,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sort_desc(sum by (namespace) (irate(container_cpu_usage_seconds_total[5m])))",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "refId": "A",
+ "step": 4
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "CPU consumed per namespace on the cluster.",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "none",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "fill": 1,
+ "id": 47,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(irate(container_cpu_usage_seconds_total{id=\"/\"}[3m])) / sum(machine_cpu_cores)",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "refId": "A",
+ "step": 4
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Percentage of total cluster CPU in use",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "percent",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "fill": 1,
+ "id": 69,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(container_memory_rss) / sum(machine_memory_bytes)",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "refId": "A",
+ "step": 4
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Percentage of total cluster memory in use",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "percent",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "fill": 1,
+ "id": 70,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum by (kubernetes_io_hostname) (irate(container_cpu_usage_seconds_total{id=~\"/system.slice/(docker|etcd).service\"}[5m]))",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "refId": "A",
+ "step": 4
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Aggregate CPU usage (seconds total) of etcd+docker",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "none",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "System and container CPU",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": true,
+ "height": 250,
+ "panels": [
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "fill": 1,
+ "id": 71,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [
+ {
+ "title": "Kubernetes Storage Metrics via Prometheus",
+ "type": "absolute",
+ "url": "https://docs.google.com/document/d/1Fh0T60T_y888LsRwC51CQHO75b2IZ3A34ZQS71s_F0g"
+ }
+ ],
+ "nullPointMode": "null",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "volumes_queue_latency",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "refId": "A",
+ "step": 4
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "volumes_queue_latency",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "none",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "fill": 1,
+ "id": 72,
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": true,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "sort": "avg",
+ "sortDesc": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [
+ {
+ "title": "Kubernetes Storage Metrics via Prometheus",
+ "type": "absolute",
+ "url": "https://docs.google.com/document/d/1Fh0T60T_y888LsRwC51CQHO75b2IZ3A34ZQS71s_F0g"
+ }
+ ],
+ "nullPointMode": "null",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "irate(cloudprovider_gce_api_request_duration_seconds_count[2m])",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{ request }}",
+ "refId": "A",
+ "step": 4
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "cloudprovider_aws_api_request_duration_seconds_count",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "none",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PR}",
+ "fill": 1,
+ "id": 73,
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": true,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "sort": "avg",
+ "sortDesc": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [
+ {
+ "title": "Kubernetes Storage Metrics via Prometheus",
+ "type": "absolute",
+ "url": "https://docs.google.com/document/d/1Fh0T60T_y888LsRwC51CQHO75b2IZ3A34ZQS71s_F0g"
+ }
+ ],
+ "nullPointMode": "null",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum (irate(storage_operation_duration_seconds_sum{kubernetes_io_hostname=~\"$Node\"}[2m])) by (operation_name,kubernetes_io_hostname)",
+ "format": "time_series",
+ "interval": "1s",
+ "intervalFactor": 1,
+ "legendFormat": "{{ operation_name }} || {{ kubernetes_io_hostname }}",
+ "refId": "A",
+ "step": 2
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "storage_operation_duration_seconds_sum",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "s",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "OpenShift Volumes",
+ "titleSize": "h6"
+ }
+ ],
+ "schemaVersion": 14,
+ "style": "dark",
+ "tags": [
+ "kubernetes",
+ "openshift"
+ ],
+ "templating": {
+ "list": [
+ {
+ "allValue": ".*",
+ "current": {},
+ "datasource": "${DS_PR}",
+ "hide": 0,
+ "includeAll": true,
+ "label": null,
+ "multi": false,
+ "name": "Node",
+ "options": [],
+ "query": "label_values(kubernetes_io_hostname)",
+ "refresh": 1,
+ "regex": "",
+ "sort": 0,
+ "tagValuesQuery": "",
+ "tags": [],
+ "tagsQuery": "",
+ "type": "query",
+ "useTags": false
+ }
+ ]
+ },
+ "time": {
+ "from": "now-30m",
+ "to": "now"
+ },
+ "timepicker": {
+ "refresh_intervals": [
+ "5s",
+ "1s",
+ "2m",
+ "20s",
+ "5m",
+ "15m",
+ "30m",
+ "1h",
+ "2h",
+ "1d"
+ ],
+ "time_options": [
+ "5m",
+ "15m",
+ "1h",
+ "6h",
+ "12h",
+ "24h",
+ "2d",
+ "7d",
+ "30d"
+ ]
+ },
+ "timezone": "browser",
+ "title": "openshift cluster monitoring",
+ "version": 6
+ }
+}
diff --git a/roles/openshift_grafana/meta/main.yml b/roles/openshift_grafana/meta/main.yml
new file mode 100644
index 000000000..8dea6f197
--- /dev/null
+++ b/roles/openshift_grafana/meta/main.yml
@@ -0,0 +1,13 @@
+---
+galaxy_info:
+ author: Eldad Marciano
+ description: Setup grafana pod
+ company: Red Hat, Inc.
+ license: Apache License, Version 2.0
+ min_ansible_version: 2.3
+ platforms:
+ - name: EL
+ versions:
+ - 7
+ categories:
+ - metrics
diff --git a/roles/openshift_grafana/tasks/gf-permissions.yml b/roles/openshift_grafana/tasks/gf-permissions.yml
new file mode 100644
index 000000000..9d3c741ee
--- /dev/null
+++ b/roles/openshift_grafana/tasks/gf-permissions.yml
@@ -0,0 +1,12 @@
+---
+- name: Create gf user on htpasswd
+ command: htpasswd -c /etc/origin/master/htpasswd gfadmin
+
+- name: Make sure master config use HTPasswdPasswordIdentityProvider
+ command: "sed -ie 's|AllowAllPasswordIdentityProvider|HTPasswdPasswordIdentityProvider\n file: /etc/origin/master/htpasswd|' /etc/origin/master/master-config.yaml"
+
+- name: Grant permission for gfuser
+ command: oc adm policy add-cluster-role-to-user cluster-reader gfadmin
+
+- name: Restart mater api
+ command: systemctl restart atomic-openshift-master-api.service
diff --git a/roles/openshift_grafana/tasks/main.yml b/roles/openshift_grafana/tasks/main.yml
new file mode 100644
index 000000000..6a06d40a9
--- /dev/null
+++ b/roles/openshift_grafana/tasks/main.yml
@@ -0,0 +1,122 @@
+---
+- name: Create grafana namespace
+ oc_project:
+ state: present
+ name: grafana
+
+- name: Configure Grafana Permissions
+ include_tasks: tasks/gf-permissions.yml
+ when: gf_oauth | default(false) | bool == true
+
+# TODO: we should grab this yaml file from openshift/origin
+- name: Templatize grafana yaml
+ template: src=grafana-ocp.yaml dest=/tmp/grafana-ocp.yaml
+ register:
+ cl_file: /tmp/grafana-ocp.yaml
+ when: gf_oauth | default(false) | bool == false
+
+# TODO: we should grab this yaml file from openshift/origin
+- name: Templatize grafana yaml
+ template: src=grafana-ocp-oauth.yaml dest=/tmp/grafana-ocp-oauth.yaml
+ register:
+ cl_file: /tmp/grafana-ocp-oauth.yaml
+ when: gf_oauth | default(false) | bool == true
+
+- name: Process the grafana file
+ oc_process:
+ namespace: grafana
+ template_name: "{{ cl_file }}"
+ create: True
+ when: gf_oauth | default(false) | bool == true
+
+- name: Wait to grafana be running
+ command: oc rollout status deployment/grafana-ocp
+
+- name: oc adm policy add-role-to-user view -z grafana-ocp -n {{ gf_prometheus_namespace }}
+ oc_adm_policy_user:
+ user: grafana-ocp
+ resource_kind: cluster-role
+ resource_name: view
+ state: present
+ role_namespace: "{{ gf_prometheus_namespace }}"
+
+- name: Get grafana route
+ oc_obj:
+ kind: route
+ name: grafana
+ namespace: grafana
+ register: route
+
+- name: Get prometheus route
+ oc_obj:
+ kind: route
+ name: prometheus
+ namespace: "{{ gf_prometheus_namespace }}"
+ register: route
+
+- name: Get the prometheus SA
+ oc_serviceaccount_secret:
+ state: list
+ service_account: prometheus
+ namespace: "{{ gf_prometheus_namespace }}"
+ register: sa
+
+- name: Get the management SA bearer token
+ set_fact:
+ management_token: "{{ sa.results | oo_filter_sa_secrets }}"
+
+- name: Ensure the SA bearer token value is read
+ oc_secret:
+ state: list
+ name: "{{ management_token }}"
+ namespace: "{{ gf_prometheus_namespace }}"
+ no_log: True
+ register: sa_secret
+
+- name: Get the SA bearer token for prometheus
+ set_fact:
+ token: "{{ sa_secret.results.encoded.token }}"
+
+- name: Convert to json
+ var:
+ ds_json: "{{ gf_body_tmp }} | to_json }}"
+
+- name: Set protocol type
+ var:
+ protocol: "{{ 'https' if {{ gf_oauth }} == true else 'http' }}"
+
+- name: Add gf datasrouce
+ uri:
+ url: "{{ protocol }}://{{ route }}/api/datasources"
+ user: admin
+ password: admin
+ method: POST
+ body: "{{ ds_json | regex_replace('grafana_name', {{ gf_datasource_name }}) | regex_replace('prometheus_url', 'https://'{{ prometheus }} ) | regex_replace('satoken', {{ token }}) }}"
+ headers:
+ Content-Type: "Content-Type: application/json"
+ register: add_ds
+
+- name: Regex setup ds name
+ replace:
+ path: "{{ lookup('file', 'openshift-cluster-monitoring.json') }}"
+ regexp: '${DS_PR}'
+ replace: '{{ gf_datasource_name }}'
+ backup: yes
+
+- name: Add new dashboard
+ uri:
+ url: "{{ protocol }}://{{ route }}/api/dashboards/db"
+ user: admin
+ password: admin
+ method: POST
+ body: "{{ lookup('file', 'openshift-cluster-monitoring.json') }}"
+ headers:
+ Content-Type: "Content-Type: application/json"
+ register: add_ds
+
+- name: Regex json tear down
+ replace:
+ path: "{{ lookup('file', 'openshift-cluster-monitoring.json') }}"
+ regexp: '${DS_PR}'
+ replace: '{{ gf_datasource_name }}'
+ backup: yes
diff --git a/roles/openshift_health_checker/openshift_checks/__init__.py b/roles/openshift_health_checker/openshift_checks/__init__.py
index 83e551b5d..b9c41d1b4 100644
--- a/roles/openshift_health_checker/openshift_checks/__init__.py
+++ b/roles/openshift_health_checker/openshift_checks/__init__.py
@@ -5,6 +5,7 @@ Health checks for OpenShift clusters.
import json
import operator
import os
+import re
import time
import collections
@@ -309,28 +310,38 @@ class OpenShiftCheck(object):
name_list = name_list.split(',')
return [name.strip() for name in name_list if name.strip()]
- @staticmethod
- def get_major_minor_version(openshift_image_tag):
+ def get_major_minor_version(self, openshift_image_tag=None):
"""Parse and return the deployed version of OpenShift as a tuple."""
- if openshift_image_tag and openshift_image_tag[0] == 'v':
- openshift_image_tag = openshift_image_tag[1:]
- # map major release versions across releases
- # to a common major version
- openshift_major_release_version = {
- "1": "3",
- }
+ version = openshift_image_tag or self.get_var("openshift_image_tag")
+ components = [int(component) for component in re.findall(r'\d+', version)]
- components = openshift_image_tag.split(".")
- if not components or len(components) < 2:
+ if len(components) < 2:
msg = "An invalid version of OpenShift was found for this host: {}"
- raise OpenShiftCheckException(msg.format(openshift_image_tag))
+ raise OpenShiftCheckException(msg.format(version))
+
+ # map major release version across releases to OCP major version
+ components[0] = {1: 3}.get(components[0], components[0])
+
+ return tuple(int(x) for x in components[:2])
+
+ def get_required_version(self, name, version_map):
+ """Return the correct required version(s) for the current (or nearest) OpenShift version."""
+ openshift_version = self.get_major_minor_version()
+
+ earliest = min(version_map)
+ latest = max(version_map)
+ if openshift_version < earliest:
+ return version_map[earliest]
+ if openshift_version > latest:
+ return version_map[latest]
- if components[0] in openshift_major_release_version:
- components[0] = openshift_major_release_version[components[0]]
+ required_version = version_map.get(openshift_version)
+ if not required_version:
+ msg = "There is no recommended version of {} for the current version of OpenShift ({})"
+ raise OpenShiftCheckException(msg.format(name, ".".join(str(comp) for comp in openshift_version)))
- components = tuple(int(x) for x in components[:2])
- return components
+ return required_version
def find_ansible_mount(self, path):
"""Return the mount point for path from ansible_mounts."""
diff --git a/roles/openshift_health_checker/openshift_checks/docker_image_availability.py b/roles/openshift_health_checker/openshift_checks/docker_image_availability.py
index 7afb8f730..d298fbab2 100644
--- a/roles/openshift_health_checker/openshift_checks/docker_image_availability.py
+++ b/roles/openshift_health_checker/openshift_checks/docker_image_availability.py
@@ -40,7 +40,7 @@ class DockerImageAvailability(DockerHostMixin, OpenShiftCheck):
# to look for images available remotely without waiting to pull them.
dependencies = ["python-docker-py", "skopeo"]
# command for checking if remote registries have an image, without docker pull
- skopeo_command = "timeout 10 skopeo inspect --tls-verify={tls} {creds} docker://{registry}/{image}"
+ skopeo_command = "{proxyvars} timeout 10 skopeo inspect --tls-verify={tls} {creds} docker://{registry}/{image}"
skopeo_example_command = "skopeo inspect [--tls-verify=false] [--creds=<user>:<pass>] docker://<registry>/<image>"
def __init__(self, *args, **kwargs):
@@ -56,7 +56,7 @@ class DockerImageAvailability(DockerHostMixin, OpenShiftCheck):
# ordered list of registries (according to inventory vars) that docker will try for unscoped images
regs = self.ensure_list("openshift_docker_additional_registries")
# currently one of these registries is added whether the user wants it or not.
- deployment_type = self.get_var("openshift_deployment_type")
+ deployment_type = self.get_var("openshift_deployment_type", default="")
if deployment_type == "origin" and "docker.io" not in regs:
regs.append("docker.io")
elif deployment_type == 'openshift-enterprise' and "registry.access.redhat.com" not in regs:
@@ -76,11 +76,20 @@ class DockerImageAvailability(DockerHostMixin, OpenShiftCheck):
if oreg_auth_user != '' and oreg_auth_password != '':
oreg_auth_user = self.template_var(oreg_auth_user)
oreg_auth_password = self.template_var(oreg_auth_password)
- self.skopeo_command_creds = "--creds={}:{}".format(quote(oreg_auth_user), quote(oreg_auth_password))
+ self.skopeo_command_creds = quote("--creds={}:{}".format(oreg_auth_user, oreg_auth_password))
# record whether we could reach a registry or not (and remember results)
self.reachable_registries = {}
+ # take note of any proxy settings needed
+ proxies = []
+ for var in ['http_proxy', 'https_proxy', 'no_proxy']:
+ # ansible vars are openshift_http_proxy, openshift_https_proxy, openshift_no_proxy
+ value = self.get_var("openshift_" + var, default=None)
+ if value:
+ proxies.append(var.upper() + "=" + quote(self.template_var(value)))
+ self.skopeo_proxy_vars = " ".join(proxies)
+
def is_active(self):
"""Skip hosts with unsupported deployment types."""
deployment_type = self.get_var("openshift_deployment_type")
@@ -249,11 +258,18 @@ class DockerImageAvailability(DockerHostMixin, OpenShiftCheck):
if not self.reachable_registries[registry]:
continue # do not keep trying unreachable registries
- args = dict(registry=registry, image=image)
- args["tls"] = "false" if registry in self.registries["insecure"] else "true"
- args["creds"] = self.skopeo_command_creds if registry == self.registries["oreg"] else ""
+ args = dict(
+ proxyvars=self.skopeo_proxy_vars,
+ tls="false" if registry in self.registries["insecure"] else "true",
+ creds=self.skopeo_command_creds if registry == self.registries["oreg"] else "",
+ registry=quote(registry),
+ image=quote(image),
+ )
- result = self.execute_module_with_retries("command", {"_raw_params": self.skopeo_command.format(**args)})
+ result = self.execute_module_with_retries("command", {
+ "_uses_shell": True,
+ "_raw_params": self.skopeo_command.format(**args),
+ })
if result.get("rc", 0) == 0 and not result.get("failed"):
return True
if result.get("rc") == 124: # RC 124 == timed out; mark unreachable
@@ -263,6 +279,10 @@ class DockerImageAvailability(DockerHostMixin, OpenShiftCheck):
def connect_to_registry(self, registry):
"""Use ansible wait_for module to test connectivity from host to registry. Returns bool."""
+ if self.skopeo_proxy_vars != "":
+ # assume we can't connect directly; just waive the test
+ return True
+
# test a simple TCP connection
host, _, port = registry.partition(":")
port = port or 443
diff --git a/roles/openshift_health_checker/openshift_checks/logging/elasticsearch.py b/roles/openshift_health_checker/openshift_checks/logging/elasticsearch.py
index 986a01f38..7f8c6ebdc 100644
--- a/roles/openshift_health_checker/openshift_checks/logging/elasticsearch.py
+++ b/roles/openshift_health_checker/openshift_checks/logging/elasticsearch.py
@@ -170,7 +170,7 @@ class Elasticsearch(LoggingCheck):
"""
errors = []
for pod_name in pods_by_name.keys():
- df_cmd = 'exec {} -- df --output=ipcent,pcent /elasticsearch/persistent'.format(pod_name)
+ df_cmd = '-c elasticsearch exec {} -- df --output=ipcent,pcent /elasticsearch/persistent'.format(pod_name)
disk_output = self.exec_oc(df_cmd, [], save_as_name='get_pv_diskspace.json')
lines = disk_output.splitlines()
# expecting one header looking like 'IUse% Use%' and one body line
diff --git a/roles/openshift_health_checker/openshift_checks/logging/kibana.py b/roles/openshift_health_checker/openshift_checks/logging/kibana.py
index 3b1cf8baa..16ec3a7f6 100644
--- a/roles/openshift_health_checker/openshift_checks/logging/kibana.py
+++ b/roles/openshift_health_checker/openshift_checks/logging/kibana.py
@@ -5,12 +5,11 @@ Module for performing checks on a Kibana logging deployment
import json
import ssl
-try:
- from urllib2 import HTTPError, URLError
- import urllib2
-except ImportError:
- from urllib.error import HTTPError, URLError
- import urllib.request as urllib2
+# pylint can't find the package when its installed in virtualenv
+# pylint: disable=import-error,no-name-in-module
+from ansible.module_utils.six.moves.urllib import request
+# pylint: disable=import-error,no-name-in-module
+from ansible.module_utils.six.moves.urllib.error import HTTPError, URLError
from openshift_checks.logging.logging import LoggingCheck, OpenShiftCheckException
@@ -65,7 +64,7 @@ class Kibana(LoggingCheck):
# Verify that the url is returning a valid response
try:
# We only care if the url connects and responds
- return_code = urllib2.urlopen(url, context=ctx).getcode()
+ return_code = request.urlopen(url, context=ctx).getcode()
except HTTPError as httperr:
return httperr.reason
except URLError as urlerr:
diff --git a/roles/openshift_health_checker/openshift_checks/ovs_version.py b/roles/openshift_health_checker/openshift_checks/ovs_version.py
index 0cad19842..58a2692bd 100644
--- a/roles/openshift_health_checker/openshift_checks/ovs_version.py
+++ b/roles/openshift_health_checker/openshift_checks/ovs_version.py
@@ -3,7 +3,7 @@ Ansible module for determining if an installed version of Open vSwitch is incomp
currently installed version of OpenShift.
"""
-from openshift_checks import OpenShiftCheck, OpenShiftCheckException
+from openshift_checks import OpenShiftCheck
from openshift_checks.mixins import NotContainerizedMixin
@@ -16,10 +16,12 @@ class OvsVersion(NotContainerizedMixin, OpenShiftCheck):
tags = ["health"]
openshift_to_ovs_version = {
- "3.7": ["2.6", "2.7", "2.8"],
- "3.6": ["2.6", "2.7", "2.8"],
- "3.5": ["2.6", "2.7"],
- "3.4": "2.4",
+ (3, 4): "2.4",
+ (3, 5): ["2.6", "2.7"],
+ (3, 6): ["2.6", "2.7", "2.8"],
+ (3, 7): ["2.6", "2.7", "2.8"],
+ (3, 8): ["2.6", "2.7", "2.8"],
+ (3, 9): ["2.6", "2.7", "2.8"],
}
def is_active(self):
@@ -40,16 +42,5 @@ class OvsVersion(NotContainerizedMixin, OpenShiftCheck):
return self.execute_module("rpm_version", args)
def get_required_ovs_version(self):
- """Return the correct Open vSwitch version for the current OpenShift version"""
- openshift_version_tuple = self.get_major_minor_version(self.get_var("openshift_image_tag"))
-
- if openshift_version_tuple < (3, 5):
- return self.openshift_to_ovs_version["3.4"]
-
- openshift_version = ".".join(str(x) for x in openshift_version_tuple)
- ovs_version = self.openshift_to_ovs_version.get(openshift_version)
- if ovs_version:
- return self.openshift_to_ovs_version[openshift_version]
-
- msg = "There is no recommended version of Open vSwitch for the current version of OpenShift: {}"
- raise OpenShiftCheckException(msg.format(openshift_version))
+ """Return the correct Open vSwitch version(s) for the current OpenShift version."""
+ return self.get_required_version("Open vSwitch", self.openshift_to_ovs_version)
diff --git a/roles/openshift_health_checker/openshift_checks/package_version.py b/roles/openshift_health_checker/openshift_checks/package_version.py
index f3a628e28..28aee8b35 100644
--- a/roles/openshift_health_checker/openshift_checks/package_version.py
+++ b/roles/openshift_health_checker/openshift_checks/package_version.py
@@ -1,8 +1,6 @@
"""Check that available RPM packages match the required versions."""
-import re
-
-from openshift_checks import OpenShiftCheck, OpenShiftCheckException
+from openshift_checks import OpenShiftCheck
from openshift_checks.mixins import NotContainerizedMixin
@@ -18,6 +16,8 @@ class PackageVersion(NotContainerizedMixin, OpenShiftCheck):
(3, 5): ["2.6", "2.7"],
(3, 6): ["2.6", "2.7", "2.8"],
(3, 7): ["2.6", "2.7", "2.8"],
+ (3, 8): ["2.6", "2.7", "2.8"],
+ (3, 9): ["2.6", "2.7", "2.8"],
}
openshift_to_docker_version = {
@@ -27,11 +27,9 @@ class PackageVersion(NotContainerizedMixin, OpenShiftCheck):
(3, 4): "1.12",
(3, 5): "1.12",
(3, 6): "1.12",
- }
-
- # map major OpenShift release versions across releases to a common major version
- map_major_release_version = {
- 1: 3,
+ (3, 7): "1.12",
+ (3, 8): "1.12",
+ (3, 9): ["1.12", "1.13"],
}
def is_active(self):
@@ -83,48 +81,8 @@ class PackageVersion(NotContainerizedMixin, OpenShiftCheck):
def get_required_ovs_version(self):
"""Return the correct Open vSwitch version(s) for the current OpenShift version."""
- openshift_version = self.get_openshift_version_tuple()
-
- earliest = min(self.openshift_to_ovs_version)
- latest = max(self.openshift_to_ovs_version)
- if openshift_version < earliest:
- return self.openshift_to_ovs_version[earliest]
- if openshift_version > latest:
- return self.openshift_to_ovs_version[latest]
-
- ovs_version = self.openshift_to_ovs_version.get(openshift_version)
- if not ovs_version:
- msg = "There is no recommended version of Open vSwitch for the current version of OpenShift: {}"
- raise OpenShiftCheckException(msg.format(".".join(str(comp) for comp in openshift_version)))
-
- return ovs_version
+ return self.get_required_version("Open vSwitch", self.openshift_to_ovs_version)
def get_required_docker_version(self):
"""Return the correct Docker version(s) for the current OpenShift version."""
- openshift_version = self.get_openshift_version_tuple()
-
- earliest = min(self.openshift_to_docker_version)
- latest = max(self.openshift_to_docker_version)
- if openshift_version < earliest:
- return self.openshift_to_docker_version[earliest]
- if openshift_version > latest:
- return self.openshift_to_docker_version[latest]
-
- docker_version = self.openshift_to_docker_version.get(openshift_version)
- if not docker_version:
- msg = "There is no recommended version of Docker for the current version of OpenShift: {}"
- raise OpenShiftCheckException(msg.format(".".join(str(comp) for comp in openshift_version)))
-
- return docker_version
-
- def get_openshift_version_tuple(self):
- """Return received image tag as a normalized (X, Y) minor version tuple."""
- version = self.get_var("openshift_image_tag")
- comps = [int(component) for component in re.findall(r'\d+', version)]
-
- if len(comps) < 2:
- msg = "An invalid version of OpenShift was found for this host: {}"
- raise OpenShiftCheckException(msg.format(version))
-
- comps[0] = self.map_major_release_version.get(comps[0], comps[0])
- return tuple(comps[0:2])
+ return self.get_required_version("Docker", self.openshift_to_docker_version)
diff --git a/roles/openshift_health_checker/test/kibana_test.py b/roles/openshift_health_checker/test/kibana_test.py
index 04a5e89c4..750d4b9e9 100644
--- a/roles/openshift_health_checker/test/kibana_test.py
+++ b/roles/openshift_health_checker/test/kibana_test.py
@@ -1,12 +1,10 @@
import pytest
import json
-try:
- import urllib2
- from urllib2 import HTTPError, URLError
-except ImportError:
- from urllib.error import HTTPError, URLError
- import urllib.request as urllib2
+# pylint can't find the package when its installed in virtualenv
+from ansible.module_utils.six.moves.urllib import request # pylint: disable=import-error
+# pylint: disable=import-error
+from ansible.module_utils.six.moves.urllib.error import HTTPError, URLError
from openshift_checks.logging.kibana import Kibana, OpenShiftCheckException
@@ -202,7 +200,7 @@ def test_verify_url_external_failure(lib_result, expect, monkeypatch):
if type(lib_result) is int:
return _http_return(lib_result)
raise lib_result
- monkeypatch.setattr(urllib2, 'urlopen', urlopen)
+ monkeypatch.setattr(request, 'urlopen', urlopen)
check = Kibana()
check._get_kibana_url = lambda: 'url'
diff --git a/roles/openshift_health_checker/test/ovs_version_test.py b/roles/openshift_health_checker/test/ovs_version_test.py
index 0238f49d5..80c7a0541 100644
--- a/roles/openshift_health_checker/test/ovs_version_test.py
+++ b/roles/openshift_health_checker/test/ovs_version_test.py
@@ -1,26 +1,7 @@
import pytest
-from openshift_checks.ovs_version import OvsVersion, OpenShiftCheckException
-
-
-def test_openshift_version_not_supported():
- def execute_module(*_):
- return {}
-
- openshift_release = '111.7.0'
-
- task_vars = dict(
- openshift=dict(common=dict()),
- openshift_release=openshift_release,
- openshift_image_tag='v' + openshift_release,
- openshift_deployment_type='origin',
- openshift_service_type='origin'
- )
-
- with pytest.raises(OpenShiftCheckException) as excinfo:
- OvsVersion(execute_module, task_vars).run()
-
- assert "no recommended version of Open vSwitch" in str(excinfo.value)
+from openshift_checks.ovs_version import OvsVersion
+from openshift_checks import OpenShiftCheckException
def test_invalid_openshift_release_format():
diff --git a/roles/openshift_health_checker/test/package_version_test.py b/roles/openshift_health_checker/test/package_version_test.py
index d2916f617..868b4bd12 100644
--- a/roles/openshift_health_checker/test/package_version_test.py
+++ b/roles/openshift_health_checker/test/package_version_test.py
@@ -1,6 +1,7 @@
import pytest
-from openshift_checks.package_version import PackageVersion, OpenShiftCheckException
+from openshift_checks.package_version import PackageVersion
+from openshift_checks import OpenShiftCheckException
def task_vars_for(openshift_release, deployment_type):
@@ -18,7 +19,7 @@ def task_vars_for(openshift_release, deployment_type):
def test_openshift_version_not_supported():
check = PackageVersion(None, task_vars_for("1.2.3", 'origin'))
- check.get_openshift_version_tuple = lambda: (3, 4, 1) # won't be in the dict
+ check.get_major_minor_version = lambda: (3, 4, 1) # won't be in the dict
with pytest.raises(OpenShiftCheckException) as excinfo:
check.get_required_ovs_version()
diff --git a/roles/openshift_hosted/tasks/storage/glusterfs_endpoints.yml b/roles/openshift_hosted/tasks/storage/glusterfs_endpoints.yml
index 77f020357..fef945d51 100644
--- a/roles/openshift_hosted/tasks/storage/glusterfs_endpoints.yml
+++ b/roles/openshift_hosted/tasks/storage/glusterfs_endpoints.yml
@@ -1,4 +1,10 @@
---
+- name: Create temp directory for doing work in
+ command: mktemp -d /tmp/openshift-hosted-ansible-XXXXXX
+ register: mktempHosted
+ changed_when: False
+ check_mode: no
+
- name: Generate GlusterFS registry endpoints
template:
src: "{{ openshift.common.examples_content_version }}/glusterfs-registry-endpoints.yml.j2"
@@ -14,3 +20,10 @@
with_items:
- "{{ mktempHosted.stdout }}/glusterfs-registry-service.yml"
- "{{ mktempHosted.stdout }}/glusterfs-registry-endpoints.yml"
+
+- name: Delete temp directory
+ file:
+ name: "{{ mktempHosted.stdout }}"
+ state: absent
+ changed_when: False
+ check_mode: no
diff --git a/roles/openshift_hosted/tasks/storage/registry_config.j2 b/roles/openshift_hosted/tasks/storage/registry_config.j2
deleted file mode 120000
index f3e82ad4f..000000000
--- a/roles/openshift_hosted/tasks/storage/registry_config.j2
+++ /dev/null
@@ -1 +0,0 @@
-../../../templates/registry_config.j2 \ No newline at end of file
diff --git a/roles/openshift_hosted_templates/files/v3.6/enterprise/registry-console.yaml b/roles/openshift_hosted_templates/files/v3.6/enterprise/registry-console.yaml
index cc3159a32..0786e2d2f 100644
--- a/roles/openshift_hosted_templates/files/v3.6/enterprise/registry-console.yaml
+++ b/roles/openshift_hosted_templates/files/v3.6/enterprise/registry-console.yaml
@@ -102,7 +102,7 @@ objects:
parameters:
- description: 'Specify "registry/repository" prefix for container image; e.g. for "registry.access.redhat.com/openshift3/registry-console:latest", set prefix "registry.access.redhat.com/openshift3/"'
name: IMAGE_PREFIX
- value: "openshift3/"
+ value: "registry.access.redhat.com/openshift3/"
- description: 'Specify component name for container image; e.g. for "registry.access.redhat.com/openshift3/registry-console:latest", use base name "registry-console"'
name: IMAGE_BASENAME
value: "registry-console"
diff --git a/roles/openshift_hosted_templates/files/v3.7/enterprise/registry-console.yaml b/roles/openshift_hosted_templates/files/v3.7/enterprise/registry-console.yaml
index 9f2e6125d..ccea54aaf 100644
--- a/roles/openshift_hosted_templates/files/v3.7/enterprise/registry-console.yaml
+++ b/roles/openshift_hosted_templates/files/v3.7/enterprise/registry-console.yaml
@@ -102,7 +102,7 @@ objects:
parameters:
- description: 'Specify "registry/repository" prefix for container image; e.g. for "registry.access.redhat.com/openshift3/registry-console:latest", set prefix "registry.access.redhat.com/openshift3/"'
name: IMAGE_PREFIX
- value: "openshift3/"
+ value: "registry.access.redhat.com/openshift3/"
- description: 'Specify component name for container image; e.g. for "registry.access.redhat.com/openshift3/registry-console:latest", use base name "registry-console"'
name: IMAGE_BASENAME
value: "registry-console"
diff --git a/roles/openshift_hosted_templates/files/v3.8/enterprise/registry-console.yaml b/roles/openshift_hosted_templates/files/v3.8/enterprise/registry-console.yaml
index f04ce06d3..15ad4e9af 100644
--- a/roles/openshift_hosted_templates/files/v3.8/enterprise/registry-console.yaml
+++ b/roles/openshift_hosted_templates/files/v3.8/enterprise/registry-console.yaml
@@ -102,7 +102,7 @@ objects:
parameters:
- description: 'Specify "registry/repository" prefix for container image; e.g. for "registry.access.redhat.com/openshift3/registry-console:latest", set prefix "registry.access.redhat.com/openshift3/"'
name: IMAGE_PREFIX
- value: "openshift3/"
+ value: "registry.access.redhat.com/openshift3/"
- description: 'Specify component name for container image; e.g. for "registry.access.redhat.com/openshift3/registry-console:latest", use base name "registry-console"'
name: IMAGE_BASENAME
value: "registry-console"
diff --git a/roles/openshift_hosted_templates/files/v3.9/enterprise/registry-console.yaml b/roles/openshift_hosted_templates/files/v3.9/enterprise/registry-console.yaml
index c178cf432..7acefa0f0 100644
--- a/roles/openshift_hosted_templates/files/v3.9/enterprise/registry-console.yaml
+++ b/roles/openshift_hosted_templates/files/v3.9/enterprise/registry-console.yaml
@@ -102,7 +102,7 @@ objects:
parameters:
- description: 'Specify "registry/repository" prefix for container image; e.g. for "registry.access.redhat.com/openshift3/registry-console:latest", set prefix "registry.access.redhat.com/openshift3/"'
name: IMAGE_PREFIX
- value: "openshift3/"
+ value: "registry.access.redhat.com/openshift3/"
- description: 'Specify component name for container image; e.g. for "registry.access.redhat.com/openshift3/registry-console:latest", use base name "registry-console"'
name: IMAGE_BASENAME
value: "registry-console"
diff --git a/roles/openshift_loadbalancer/templates/haproxy.cfg.j2 b/roles/openshift_loadbalancer/templates/haproxy.cfg.j2
index de5a8d7c2..823f012af 100644
--- a/roles/openshift_loadbalancer/templates/haproxy.cfg.j2
+++ b/roles/openshift_loadbalancer/templates/haproxy.cfg.j2
@@ -38,7 +38,8 @@ defaults
timeout check 10s
maxconn {{ openshift_loadbalancer_default_maxconn | default(20000) }}
-listen stats :9000
+listen stats
+ bind :9000
mode http
stats enable
stats uri /
diff --git a/roles/openshift_logging/tasks/annotate_ops_projects.yaml b/roles/openshift_logging/tasks/annotate_ops_projects.yaml
index 4a2ee64f0..6fdba6580 100644
--- a/roles/openshift_logging/tasks/annotate_ops_projects.yaml
+++ b/roles/openshift_logging/tasks/annotate_ops_projects.yaml
@@ -12,6 +12,7 @@
separator: '#'
content:
metadata#annotations#openshift.io/logging.ui.hostname: "{{ openshift_logging_kibana_ops_hostname }}"
+ metadata#annotations#openshift.io/logging.data.prefix: ".operations"
with_items: "{{ __logging_ops_projects.stdout.split(' ') }}"
loop_control:
loop_var: project
diff --git a/roles/openshift_logging/tasks/delete_logging.yaml b/roles/openshift_logging/tasks/delete_logging.yaml
index fbc3e3fd1..ced7397b5 100644
--- a/roles/openshift_logging/tasks/delete_logging.yaml
+++ b/roles/openshift_logging/tasks/delete_logging.yaml
@@ -131,13 +131,13 @@
when:
not openshift_logging_install_eventrouter | default(false) | bool
-# Update asset config in openshift-web-console namespace
-- name: Remove Kibana route information from web console asset config
+# Update console config in openshift-web-console namespace
+- name: Remove Kibana route information from the web console config
include_role:
name: openshift_web_console
- tasks_from: update_asset_config.yml
+ tasks_from: update_console_config.yml
vars:
- asset_config_edits:
- - key: loggingPublicURL
+ console_config_edits:
+ - key: clusterInfo#loggingPublicURL
value: ""
when: openshift_web_console_install | default(true) | bool
diff --git a/roles/openshift_logging/tasks/generate_certs.yaml b/roles/openshift_logging/tasks/generate_certs.yaml
index 0d7f8c056..a40449bf6 100644
--- a/roles/openshift_logging/tasks/generate_certs.yaml
+++ b/roles/openshift_logging/tasks/generate_certs.yaml
@@ -19,7 +19,7 @@
command: >
{{ openshift_client_binary }} adm --config={{ mktemp.stdout }}/admin.kubeconfig ca create-signer-cert
--key={{generated_certs_dir}}/ca.key --cert={{generated_certs_dir}}/ca.crt
- --serial={{generated_certs_dir}}/ca.serial.txt --name=logging-signer-test
+ --serial={{generated_certs_dir}}/ca.serial.txt --name=logging-signer-test --overwrite=false
check_mode: no
when:
- not ca_key_file.stat.exists
diff --git a/roles/openshift_logging/tasks/install_logging.yaml b/roles/openshift_logging/tasks/install_logging.yaml
index ebd2d747b..3afd8680f 100644
--- a/roles/openshift_logging/tasks/install_logging.yaml
+++ b/roles/openshift_logging/tasks/install_logging.yaml
@@ -87,7 +87,7 @@
openshift_logging_elasticsearch_storage_type: "{{ elasticsearch_storage_type }}"
openshift_logging_elasticsearch_pvc_pv_selector: "{{ openshift_logging_es_pv_selector }}"
- openshift_logging_elasticsearch_pvc_storage_class_name: "{{ openshift_logging_es_pvc_storage_class_name }}"
+ openshift_logging_elasticsearch_pvc_storage_class_name: "{{ openshift_logging_es_pvc_storage_class_name | default() }}"
openshift_logging_elasticsearch_nodeselector: "{{ openshift_logging_es_nodeselector if outer_item.0.nodeSelector | default(None) is none else outer_item.0.nodeSelector }}"
openshift_logging_elasticsearch_storage_group: "{{ [openshift_logging_es_storage_group] if outer_item.0.storageGroups | default([]) | length == 0 else outer_item.0.storageGroups }}"
_es_containers: "{{ outer_item.0.containers}}"
@@ -114,7 +114,7 @@
openshift_logging_elasticsearch_storage_type: "{{ elasticsearch_storage_type }}"
openshift_logging_elasticsearch_pvc_pv_selector: "{{ openshift_logging_es_pv_selector }}"
- openshift_logging_elasticsearch_pvc_storage_class_name: "{{ openshift_logging_es_pvc_storage_class_name }}"
+ openshift_logging_elasticsearch_pvc_storage_class_name: "{{ openshift_logging_es_pvc_storage_class_name | default() }}"
with_sequence: count={{ openshift_logging_es_cluster_size | int - openshift_logging_facts.elasticsearch.deploymentconfigs.keys() | count }}
loop_control:
@@ -151,7 +151,7 @@
openshift_logging_elasticsearch_pvc_size: "{{ openshift_logging_es_ops_pvc_size }}"
openshift_logging_elasticsearch_pvc_dynamic: "{{ openshift_logging_es_ops_pvc_dynamic }}"
openshift_logging_elasticsearch_pvc_pv_selector: "{{ openshift_logging_es_ops_pv_selector }}"
- openshift_logging_elasticsearch_pvc_storage_class_name: "{{ openshift_logging_es_ops_pvc_storage_class_name }}"
+ openshift_logging_elasticsearch_pvc_storage_class_name: "{{ openshift_logging_es_ops_pvc_storage_class_name | default() }}"
openshift_logging_elasticsearch_memory_limit: "{{ openshift_logging_es_ops_memory_limit }}"
openshift_logging_elasticsearch_cpu_limit: "{{ openshift_logging_es_ops_cpu_limit }}"
openshift_logging_elasticsearch_cpu_request: "{{ openshift_logging_es_ops_cpu_request }}"
@@ -193,7 +193,7 @@
openshift_logging_elasticsearch_pvc_size: "{{ openshift_logging_es_ops_pvc_size }}"
openshift_logging_elasticsearch_pvc_dynamic: "{{ openshift_logging_es_ops_pvc_dynamic }}"
openshift_logging_elasticsearch_pvc_pv_selector: "{{ openshift_logging_es_ops_pv_selector }}"
- openshift_logging_elasticsearch_pvc_storage_class_name: "{{ openshift_logging_es_ops_pvc_storage_class_name }}"
+ openshift_logging_elasticsearch_pvc_storage_class_name: "{{ openshift_logging_es_ops_pvc_storage_class_name | default() }}"
openshift_logging_elasticsearch_memory_limit: "{{ openshift_logging_es_ops_memory_limit }}"
openshift_logging_elasticsearch_cpu_limit: "{{ openshift_logging_es_ops_cpu_limit }}"
openshift_logging_elasticsearch_cpu_request: "{{ openshift_logging_es_ops_cpu_request }}"
@@ -321,9 +321,9 @@
- name: Add Kibana route information to web console asset config
include_role:
name: openshift_web_console
- tasks_from: update_asset_config.yml
+ tasks_from: update_console_config.yml
vars:
- asset_config_edits:
- - key: loggingPublicURL
+ console_config_edits:
+ - key: clusterInfo#loggingPublicURL
value: "https://{{ openshift_logging_kibana_hostname }}"
when: openshift_web_console_install | default(true) | bool
diff --git a/roles/openshift_logging/tasks/procure_server_certs.yaml b/roles/openshift_logging/tasks/procure_server_certs.yaml
index bc817075d..d28d1d160 100644
--- a/roles/openshift_logging/tasks/procure_server_certs.yaml
+++ b/roles/openshift_logging/tasks/procure_server_certs.yaml
@@ -30,7 +30,7 @@
{{ openshift_client_binary }} adm --config={{ mktemp.stdout }}/admin.kubeconfig ca create-server-cert
--key={{generated_certs_dir}}/{{cert_info.procure_component}}.key --cert={{generated_certs_dir}}/{{cert_info.procure_component}}.crt
--hostnames={{cert_info.hostnames|quote}} --signer-cert={{generated_certs_dir}}/ca.crt --signer-key={{generated_certs_dir}}/ca.key
- --signer-serial={{generated_certs_dir}}/ca.serial.txt
+ --signer-serial={{generated_certs_dir}}/ca.serial.txt --overwrite=false
check_mode: no
when:
- cert_info.hostnames is defined
diff --git a/roles/openshift_logging_elasticsearch/tasks/get_es_version.yml b/roles/openshift_logging_elasticsearch/tasks/get_es_version.yml
index 9182bddb2..16de6f252 100644
--- a/roles/openshift_logging_elasticsearch/tasks/get_es_version.yml
+++ b/roles/openshift_logging_elasticsearch/tasks/get_es_version.yml
@@ -1,6 +1,6 @@
---
- command: >
- oc get pod -l component=es,provider=openshift -n {{ openshift_logging_elasticsearch_namespace }} -o jsonpath={.items[*].metadata.name}
+ oc get pod -l component=es,provider=openshift -n {{ openshift_logging_elasticsearch_namespace }} -o jsonpath={.items[?(@.status.phase==\"Running\")].metadata.name}
register: _cluster_pods
- name: "Getting ES version for logging-es cluster"
@@ -10,7 +10,7 @@
when: _cluster_pods.stdout_lines | count > 0
- command: >
- oc get pod -l component=es-ops,provider=openshift -n {{ openshift_logging_elasticsearch_namespace }} -o jsonpath={.items[*].metadata.name}
+ oc get pod -l component=es-ops,provider=openshift -n {{ openshift_logging_elasticsearch_namespace }} -o jsonpath={.items[?(@.status.phase==\"Running\")].metadata.name}
register: _ops_cluster_pods
- name: "Getting ES version for logging-es-ops cluster"
diff --git a/roles/openshift_logging_elasticsearch/tasks/restart_cluster.yml b/roles/openshift_logging_elasticsearch/tasks/restart_cluster.yml
index d55beec86..6bce13d1d 100644
--- a/roles/openshift_logging_elasticsearch/tasks/restart_cluster.yml
+++ b/roles/openshift_logging_elasticsearch/tasks/restart_cluster.yml
@@ -19,7 +19,7 @@
## get all pods for the cluster
- command: >
- oc get pod -l component={{ _cluster_component }},provider=openshift -n {{ openshift_logging_elasticsearch_namespace }} -o jsonpath={.items[*].metadata.name}
+ oc get pod -l component={{ _cluster_component }},provider=openshift -n {{ openshift_logging_elasticsearch_namespace }} -o jsonpath={.items[?(@.status.phase==\"Running\")].metadata.name}
register: _cluster_pods
- name: "Disable shard balancing for logging-{{ _cluster_component }} cluster"
@@ -64,7 +64,7 @@
## we may need a new first pod to run against -- fetch them all again
- command: >
- oc get pod -l component={{ _cluster_component }},provider=openshift -n {{ openshift_logging_elasticsearch_namespace }} -o jsonpath={.items[*].metadata.name}
+ oc get pod -l component={{ _cluster_component }},provider=openshift -n {{ openshift_logging_elasticsearch_namespace }} -o jsonpath={.items[?(@.status.phase==\"Running\")].metadata.name}
register: _cluster_pods
- name: "Enable shard balancing for logging-{{ _cluster_component }} cluster"
diff --git a/roles/openshift_management/files/templates/cloudforms/cfme-backup-job.yaml b/roles/openshift_management/files/templates/cloudforms/cfme-backup-job.yaml
index c3bc1d20c..48d1d4e26 100644
--- a/roles/openshift_management/files/templates/cloudforms/cfme-backup-job.yaml
+++ b/roles/openshift_management/files/templates/cloudforms/cfme-backup-job.yaml
@@ -9,7 +9,7 @@ spec:
spec:
containers:
- name: postgresql
- image: brew-pulp-docker01.web.prod.ext.phx2.redhat.com:8888/cloudforms46/cfme-openshift-postgresql:latest
+ image: registry.access.redhat.com/cloudforms46-beta/cfme-openshift-postgresql:latest
command:
- "/opt/rh/cfme-container-scripts/backup_db"
env:
diff --git a/roles/openshift_management/files/templates/cloudforms/cfme-restore-job.yaml b/roles/openshift_management/files/templates/cloudforms/cfme-restore-job.yaml
index 8b23f8a33..7fd4fc2e1 100644
--- a/roles/openshift_management/files/templates/cloudforms/cfme-restore-job.yaml
+++ b/roles/openshift_management/files/templates/cloudforms/cfme-restore-job.yaml
@@ -9,7 +9,7 @@ spec:
spec:
containers:
- name: postgresql
- image: brew-pulp-docker01.web.prod.ext.phx2.redhat.com:8888/cloudforms46/cfme-openshift-postgresql:latest
+ image: registry.access.redhat.com/cloudforms46-beta/cfme-openshift-postgresql:latest
command:
- "/opt/rh/cfme-container-scripts/restore_db"
env:
diff --git a/roles/openshift_management/files/templates/cloudforms/cfme-template-ext-db.yaml b/roles/openshift_management/files/templates/cloudforms/cfme-template-ext-db.yaml
index 4a04f3372..9866c29c3 100644
--- a/roles/openshift_management/files/templates/cloudforms/cfme-template-ext-db.yaml
+++ b/roles/openshift_management/files/templates/cloudforms/cfme-template-ext-db.yaml
@@ -31,6 +31,7 @@ objects:
name: "${NAME}-secrets"
stringData:
pg-password: "${DATABASE_PASSWORD}"
+ admin-password: "${APPLICATION_ADMIN_PASSWORD}"
database-url: postgresql://${DATABASE_USER}:${DATABASE_PASSWORD}@${DATABASE_SERVICE_NAME}/${DATABASE_NAME}?encoding=utf8&pool=5&wait_timeout=5
v2-key: "${V2_KEY}"
- apiVersion: v1
@@ -90,15 +91,15 @@ objects:
- name: cloudforms
image: "${FRONTEND_APPLICATION_IMG_NAME}:${FRONTEND_APPLICATION_IMG_TAG}"
livenessProbe:
- tcpSocket:
- port: 80
+ exec:
+ command:
+ - pidof
+ - MIQ Server
initialDelaySeconds: 480
timeoutSeconds: 3
readinessProbe:
- httpGet:
- path: "/"
+ tcpSocket:
port: 80
- scheme: HTTP
initialDelaySeconds: 200
timeoutSeconds: 3
ports:
@@ -126,6 +127,11 @@ objects:
secretKeyRef:
name: "${NAME}-secrets"
key: v2-key
+ - name: APPLICATION_ADMIN_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: "${NAME}-secrets"
+ key: admin-password
- name: ANSIBLE_ADMIN_PASSWORD
valueFrom:
secretKeyRef:
@@ -433,18 +439,173 @@ objects:
<VirtualHost *:80>
KeepAlive on
+ # Without ServerName mod_auth_mellon compares against http:// and not https:// from the IdP
+ ServerName https://%{REQUEST_HOST}
+
ProxyPreserveHost on
- ProxyPass /ws/ ws://${NAME}/ws/
- ProxyPassReverse /ws/ ws://${NAME}/ws/
- ProxyPass / http://${NAME}/
+
+ RewriteCond %{REQUEST_URI} ^/ws [NC]
+ RewriteCond %{HTTP:UPGRADE} ^websocket$ [NC]
+ RewriteCond %{HTTP:CONNECTION} ^Upgrade$ [NC]
+ RewriteRule .* ws://${NAME}%{REQUEST_URI} [P,QSA,L]
+
+ # For httpd, some ErrorDocuments must by served by the httpd pod
+ RewriteCond %{REQUEST_URI} !^/proxy_pages
+
+ # For SAML /saml2 is only served by mod_auth_mellon in the httpd pod
+ RewriteCond %{REQUEST_URI} !^/saml2
+ RewriteRule ^/ http://${NAME}%{REQUEST_URI} [P,QSA,L]
ProxyPassReverse / http://${NAME}/
+
+ # Ensures httpd stdout/stderr are seen by docker logs.
+ ErrorLog "| /usr/bin/tee /proc/1/fd/2 /var/log/httpd/error_log"
+ CustomLog "| /usr/bin/tee /proc/1/fd/1 /var/log/httpd/access_log" common
</VirtualHost>
+ authentication.conf: |
+ # Load appropriate authentication configuration files
+ #
+ Include "conf.d/configuration-${HTTPD_AUTH_TYPE}-auth"
+ configuration-internal-auth: |
+ # Internal authentication
+ #
+ configuration-external-auth: |
+ Include "conf.d/external-auth-load-modules-conf"
+
+ <Location /dashboard/kerberos_authenticate>
+ AuthType Kerberos
+ AuthName "Kerberos Login"
+ KrbMethodNegotiate On
+ KrbMethodK5Passwd Off
+ KrbAuthRealms ${HTTPD_AUTH_KERBEROS_REALMS}
+ Krb5KeyTab /etc/http.keytab
+ KrbServiceName Any
+ Require pam-account httpd-auth
+
+ ErrorDocument 401 /proxy_pages/invalid_sso_credentials.js
+ </Location>
+
+ Include "conf.d/external-auth-login-form-conf"
+ Include "conf.d/external-auth-application-api-conf"
+ Include "conf.d/external-auth-lookup-user-details-conf"
+ Include "conf.d/external-auth-remote-user-conf"
+ configuration-active-directory-auth: |
+ Include "conf.d/external-auth-load-modules-conf"
+
+ <Location /dashboard/kerberos_authenticate>
+ AuthType Kerberos
+ AuthName "Kerberos Login"
+ KrbMethodNegotiate On
+ KrbMethodK5Passwd Off
+ KrbAuthRealms ${HTTPD_AUTH_KERBEROS_REALMS}
+ Krb5KeyTab /etc/krb5.keytab
+ KrbServiceName Any
+ Require pam-account httpd-auth
+
+ ErrorDocument 401 /proxy_pages/invalid_sso_credentials.js
+ </Location>
+
+ Include "conf.d/external-auth-login-form-conf"
+ Include "conf.d/external-auth-application-api-conf"
+ Include "conf.d/external-auth-lookup-user-details-conf"
+ Include "conf.d/external-auth-remote-user-conf"
+ configuration-saml-auth: |
+ LoadModule auth_mellon_module modules/mod_auth_mellon.so
+
+ <Location />
+ MellonEnable "info"
+
+ MellonIdPMetadataFile "/etc/httpd/saml2/idp-metadata.xml"
+
+ MellonSPPrivateKeyFile "/etc/httpd/saml2/sp-key.key"
+ MellonSPCertFile "/etc/httpd/saml2/sp-cert.cert"
+ MellonSPMetadataFile "/etc/httpd/saml2/sp-metadata.xml"
+
+ MellonVariable "sp-cookie"
+ MellonSecureCookie On
+ MellonCookiePath "/"
+
+ MellonIdP "IDP"
+
+ MellonEndpointPath "/saml2"
+
+ MellonUser username
+ MellonMergeEnvVars On
+
+ MellonSetEnvNoPrefix "REMOTE_USER" username
+ MellonSetEnvNoPrefix "REMOTE_USER_EMAIL" email
+ MellonSetEnvNoPrefix "REMOTE_USER_FIRSTNAME" firstname
+ MellonSetEnvNoPrefix "REMOTE_USER_LASTNAME" lastname
+ MellonSetEnvNoPrefix "REMOTE_USER_FULLNAME" fullname
+ MellonSetEnvNoPrefix "REMOTE_USER_GROUPS" groups
+ </Location>
+
+ <Location /saml_login>
+ AuthType "Mellon"
+ MellonEnable "auth"
+ Require valid-user
+ </Location>
+
+ Include "conf.d/external-auth-remote-user-conf"
+ external-auth-load-modules-conf: |
+ LoadModule authnz_pam_module modules/mod_authnz_pam.so
+ LoadModule intercept_form_submit_module modules/mod_intercept_form_submit.so
+ LoadModule lookup_identity_module modules/mod_lookup_identity.so
+ LoadModule auth_kerb_module modules/mod_auth_kerb.so
+ external-auth-login-form-conf: |
+ <Location /dashboard/external_authenticate>
+ InterceptFormPAMService httpd-auth
+ InterceptFormLogin user_name
+ InterceptFormPassword user_password
+ InterceptFormLoginSkip admin
+ InterceptFormClearRemoteUserForSkipped on
+ </Location>
+ external-auth-application-api-conf: |
+ <LocationMatch ^/api>
+ SetEnvIf Authorization '^Basic +YWRtaW46' let_admin_in
+ SetEnvIf X-Auth-Token '^.+$' let_api_token_in
+ SetEnvIf X-MIQ-Token '^.+$' let_sys_token_in
+
+ AuthType Basic
+ AuthName "External Authentication (httpd) for API"
+ AuthBasicProvider PAM
+
+ AuthPAMService httpd-auth
+ Require valid-user
+ Order Allow,Deny
+ Allow from env=let_admin_in
+ Allow from env=let_api_token_in
+ Allow from env=let_sys_token_in
+ Satisfy Any
+ </LocationMatch>
+ external-auth-lookup-user-details-conf: |
+ <LocationMatch ^/dashboard/external_authenticate$|^/dashboard/kerberos_authenticate$|^/api>
+ LookupUserAttr mail REMOTE_USER_EMAIL
+ LookupUserAttr givenname REMOTE_USER_FIRSTNAME
+ LookupUserAttr sn REMOTE_USER_LASTNAME
+ LookupUserAttr displayname REMOTE_USER_FULLNAME
+ LookupUserAttr domainname REMOTE_USER_DOMAIN
+
+ LookupUserGroups REMOTE_USER_GROUPS ":"
+ LookupDbusTimeout 5000
+ </LocationMatch>
+ external-auth-remote-user-conf: |
+ RequestHeader unset X_REMOTE_USER
+
+ RequestHeader set X_REMOTE_USER %{REMOTE_USER}e env=REMOTE_USER
+ RequestHeader set X_EXTERNAL_AUTH_ERROR %{EXTERNAL_AUTH_ERROR}e env=EXTERNAL_AUTH_ERROR
+ RequestHeader set X_REMOTE_USER_EMAIL %{REMOTE_USER_EMAIL}e env=REMOTE_USER_EMAIL
+ RequestHeader set X_REMOTE_USER_FIRSTNAME %{REMOTE_USER_FIRSTNAME}e env=REMOTE_USER_FIRSTNAME
+ RequestHeader set X_REMOTE_USER_LASTNAME %{REMOTE_USER_LASTNAME}e env=REMOTE_USER_LASTNAME
+ RequestHeader set X_REMOTE_USER_FULLNAME %{REMOTE_USER_FULLNAME}e env=REMOTE_USER_FULLNAME
+ RequestHeader set X_REMOTE_USER_GROUPS %{REMOTE_USER_GROUPS}e env=REMOTE_USER_GROUPS
+ RequestHeader set X_REMOTE_USER_DOMAIN %{REMOTE_USER_DOMAIN}e env=REMOTE_USER_DOMAIN
- apiVersion: v1
kind: ConfigMap
metadata:
name: "${HTTPD_SERVICE_NAME}-auth-configs"
data:
auth-type: internal
+ auth-kerberos-realms: undefined
auth-configuration.conf: |
# External Authentication Configuration File
#
@@ -464,6 +625,20 @@ objects:
selector:
name: httpd
- apiVersion: v1
+ kind: Service
+ metadata:
+ name: "${HTTPD_DBUS_API_SERVICE_NAME}"
+ annotations:
+ description: Exposes the httpd server dbus api
+ service.alpha.openshift.io/dependencies: '[{"name":"${NAME}","namespace":"","kind":"Service"}]'
+ spec:
+ ports:
+ - name: http-dbus-api
+ port: 8080
+ targetPort: 8080
+ selector:
+ name: httpd
+- apiVersion: v1
kind: DeploymentConfig
metadata:
name: "${HTTPD_SERVICE_NAME}"
@@ -497,6 +672,9 @@ objects:
image: "${HTTPD_IMG_NAME}:${HTTPD_IMG_TAG}"
ports:
- containerPort: 80
+ protocol: TCP
+ - containerPort: 8080
+ protocol: TCP
livenessProbe:
exec:
command:
@@ -526,6 +704,11 @@ objects:
configMapKeyRef:
name: "${HTTPD_SERVICE_NAME}-auth-configs"
key: auth-type
+ - name: HTTPD_AUTH_KERBEROS_REALMS
+ valueFrom:
+ configMapKeyRef:
+ name: "${HTTPD_SERVICE_NAME}-auth-configs"
+ key: auth-kerberos-realms
lifecycle:
postStart:
exec:
@@ -581,6 +764,11 @@ parameters:
displayName: Application Database Region
description: Database region that will be used for application.
value: '0'
+- name: APPLICATION_ADMIN_PASSWORD
+ displayName: Application Admin Password
+ required: true
+ description: Admin password that will be set on the application.
+ value: smartvm
- name: ANSIBLE_DATABASE_NAME
displayName: Ansible PostgreSQL database name
required: true
@@ -678,7 +866,7 @@ parameters:
- name: MEMCACHED_IMG_NAME
displayName: Memcached Image Name
description: This is the Memcached image name requested to deploy.
- value: brew-pulp-docker01.web.prod.ext.phx2.redhat.com:8888/cloudforms46/cfme-openshift-memcached
+ value: registry.access.redhat.com/cloudforms46-beta/cfme-openshift-memcached
- name: MEMCACHED_IMG_TAG
displayName: Memcached Image Tag
description: This is the Memcached image tag/version requested to deploy.
@@ -686,11 +874,11 @@ parameters:
- name: FRONTEND_APPLICATION_IMG_NAME
displayName: Frontend Application Image Name
description: This is the Frontend Application image name requested to deploy.
- value: brew-pulp-docker01.web.prod.ext.phx2.redhat.com:8888/cloudforms46/cfme-openshift-app-ui
+ value: registry.access.redhat.com/cloudforms46-beta/cfme-openshift-app-ui
- name: BACKEND_APPLICATION_IMG_NAME
displayName: Backend Application Image Name
description: This is the Backend Application image name requested to deploy.
- value: brew-pulp-docker01.web.prod.ext.phx2.redhat.com:8888/cloudforms46/cfme-openshift-app
+ value: registry.access.redhat.com/cloudforms46-beta/cfme-openshift-app
- name: FRONTEND_APPLICATION_IMG_TAG
displayName: Front end Application Image Tag
description: This is the CloudForms Frontend Application image tag/version requested to deploy.
@@ -702,7 +890,7 @@ parameters:
- name: ANSIBLE_IMG_NAME
displayName: Ansible Image Name
description: This is the Ansible image name requested to deploy.
- value: brew-pulp-docker01.web.prod.ext.phx2.redhat.com:8888/cloudforms46/cfme-openshift-embedded-ansible
+ value: registry.access.redhat.com/cloudforms46-beta/cfme-openshift-embedded-ansible
- name: ANSIBLE_IMG_TAG
displayName: Ansible Image Tag
description: This is the Ansible image tag/version requested to deploy.
@@ -730,10 +918,15 @@ parameters:
displayName: Apache httpd Service Name
description: The name of the OpenShift Service exposed for the httpd container.
value: httpd
+- name: HTTPD_DBUS_API_SERVICE_NAME
+ required: true
+ displayName: Apache httpd DBus API Service Name
+ description: The name of httpd dbus api service.
+ value: httpd-dbus-api
- name: HTTPD_IMG_NAME
displayName: Apache httpd Image Name
description: This is the httpd image name requested to deploy.
- value: brew-pulp-docker01.web.prod.ext.phx2.redhat.com:8888/cloudforms46/cfme-openshift-httpd
+ value: registry.access.redhat.com/cloudforms46-beta/cfme-openshift-httpd
- name: HTTPD_IMG_TAG
displayName: Apache httpd Image Tag
description: This is the httpd image tag/version requested to deploy.
diff --git a/roles/openshift_management/files/templates/cloudforms/cfme-template.yaml b/roles/openshift_management/files/templates/cloudforms/cfme-template.yaml
index d7c9f5af7..5c757b6c2 100644
--- a/roles/openshift_management/files/templates/cloudforms/cfme-template.yaml
+++ b/roles/openshift_management/files/templates/cloudforms/cfme-template.yaml
@@ -31,6 +31,7 @@ objects:
name: "${NAME}-secrets"
stringData:
pg-password: "${DATABASE_PASSWORD}"
+ admin-password: "${APPLICATION_ADMIN_PASSWORD}"
database-url: postgresql://${DATABASE_USER}:${DATABASE_PASSWORD}@${DATABASE_SERVICE_NAME}/${DATABASE_NAME}?encoding=utf8&pool=5&wait_timeout=5
v2-key: "${V2_KEY}"
- apiVersion: v1
@@ -128,18 +129,173 @@ objects:
<VirtualHost *:80>
KeepAlive on
+ # Without ServerName mod_auth_mellon compares against http:// and not https:// from the IdP
+ ServerName https://%{REQUEST_HOST}
+
ProxyPreserveHost on
- ProxyPass /ws/ ws://${NAME}/ws/
- ProxyPassReverse /ws/ ws://${NAME}/ws/
- ProxyPass / http://${NAME}/
+
+ RewriteCond %{REQUEST_URI} ^/ws [NC]
+ RewriteCond %{HTTP:UPGRADE} ^websocket$ [NC]
+ RewriteCond %{HTTP:CONNECTION} ^Upgrade$ [NC]
+ RewriteRule .* ws://${NAME}%{REQUEST_URI} [P,QSA,L]
+
+ # For httpd, some ErrorDocuments must by served by the httpd pod
+ RewriteCond %{REQUEST_URI} !^/proxy_pages
+
+ # For SAML /saml2 is only served by mod_auth_mellon in the httpd pod
+ RewriteCond %{REQUEST_URI} !^/saml2
+ RewriteRule ^/ http://${NAME}%{REQUEST_URI} [P,QSA,L]
ProxyPassReverse / http://${NAME}/
+
+ # Ensures httpd stdout/stderr are seen by docker logs.
+ ErrorLog "| /usr/bin/tee /proc/1/fd/2 /var/log/httpd/error_log"
+ CustomLog "| /usr/bin/tee /proc/1/fd/1 /var/log/httpd/access_log" common
</VirtualHost>
+ authentication.conf: |
+ # Load appropriate authentication configuration files
+ #
+ Include "conf.d/configuration-${HTTPD_AUTH_TYPE}-auth"
+ configuration-internal-auth: |
+ # Internal authentication
+ #
+ configuration-external-auth: |
+ Include "conf.d/external-auth-load-modules-conf"
+
+ <Location /dashboard/kerberos_authenticate>
+ AuthType Kerberos
+ AuthName "Kerberos Login"
+ KrbMethodNegotiate On
+ KrbMethodK5Passwd Off
+ KrbAuthRealms ${HTTPD_AUTH_KERBEROS_REALMS}
+ Krb5KeyTab /etc/http.keytab
+ KrbServiceName Any
+ Require pam-account httpd-auth
+
+ ErrorDocument 401 /proxy_pages/invalid_sso_credentials.js
+ </Location>
+
+ Include "conf.d/external-auth-login-form-conf"
+ Include "conf.d/external-auth-application-api-conf"
+ Include "conf.d/external-auth-lookup-user-details-conf"
+ Include "conf.d/external-auth-remote-user-conf"
+ configuration-active-directory-auth: |
+ Include "conf.d/external-auth-load-modules-conf"
+
+ <Location /dashboard/kerberos_authenticate>
+ AuthType Kerberos
+ AuthName "Kerberos Login"
+ KrbMethodNegotiate On
+ KrbMethodK5Passwd Off
+ KrbAuthRealms ${HTTPD_AUTH_KERBEROS_REALMS}
+ Krb5KeyTab /etc/krb5.keytab
+ KrbServiceName Any
+ Require pam-account httpd-auth
+
+ ErrorDocument 401 /proxy_pages/invalid_sso_credentials.js
+ </Location>
+
+ Include "conf.d/external-auth-login-form-conf"
+ Include "conf.d/external-auth-application-api-conf"
+ Include "conf.d/external-auth-lookup-user-details-conf"
+ Include "conf.d/external-auth-remote-user-conf"
+ configuration-saml-auth: |
+ LoadModule auth_mellon_module modules/mod_auth_mellon.so
+
+ <Location />
+ MellonEnable "info"
+
+ MellonIdPMetadataFile "/etc/httpd/saml2/idp-metadata.xml"
+
+ MellonSPPrivateKeyFile "/etc/httpd/saml2/sp-key.key"
+ MellonSPCertFile "/etc/httpd/saml2/sp-cert.cert"
+ MellonSPMetadataFile "/etc/httpd/saml2/sp-metadata.xml"
+
+ MellonVariable "sp-cookie"
+ MellonSecureCookie On
+ MellonCookiePath "/"
+
+ MellonIdP "IDP"
+
+ MellonEndpointPath "/saml2"
+
+ MellonUser username
+ MellonMergeEnvVars On
+
+ MellonSetEnvNoPrefix "REMOTE_USER" username
+ MellonSetEnvNoPrefix "REMOTE_USER_EMAIL" email
+ MellonSetEnvNoPrefix "REMOTE_USER_FIRSTNAME" firstname
+ MellonSetEnvNoPrefix "REMOTE_USER_LASTNAME" lastname
+ MellonSetEnvNoPrefix "REMOTE_USER_FULLNAME" fullname
+ MellonSetEnvNoPrefix "REMOTE_USER_GROUPS" groups
+ </Location>
+
+ <Location /saml_login>
+ AuthType "Mellon"
+ MellonEnable "auth"
+ Require valid-user
+ </Location>
+
+ Include "conf.d/external-auth-remote-user-conf"
+ external-auth-load-modules-conf: |
+ LoadModule authnz_pam_module modules/mod_authnz_pam.so
+ LoadModule intercept_form_submit_module modules/mod_intercept_form_submit.so
+ LoadModule lookup_identity_module modules/mod_lookup_identity.so
+ LoadModule auth_kerb_module modules/mod_auth_kerb.so
+ external-auth-login-form-conf: |
+ <Location /dashboard/external_authenticate>
+ InterceptFormPAMService httpd-auth
+ InterceptFormLogin user_name
+ InterceptFormPassword user_password
+ InterceptFormLoginSkip admin
+ InterceptFormClearRemoteUserForSkipped on
+ </Location>
+ external-auth-application-api-conf: |
+ <LocationMatch ^/api>
+ SetEnvIf Authorization '^Basic +YWRtaW46' let_admin_in
+ SetEnvIf X-Auth-Token '^.+$' let_api_token_in
+ SetEnvIf X-MIQ-Token '^.+$' let_sys_token_in
+
+ AuthType Basic
+ AuthName "External Authentication (httpd) for API"
+ AuthBasicProvider PAM
+
+ AuthPAMService httpd-auth
+ Require valid-user
+ Order Allow,Deny
+ Allow from env=let_admin_in
+ Allow from env=let_api_token_in
+ Allow from env=let_sys_token_in
+ Satisfy Any
+ </LocationMatch>
+ external-auth-lookup-user-details-conf: |
+ <LocationMatch ^/dashboard/external_authenticate$|^/dashboard/kerberos_authenticate$|^/api>
+ LookupUserAttr mail REMOTE_USER_EMAIL
+ LookupUserAttr givenname REMOTE_USER_FIRSTNAME
+ LookupUserAttr sn REMOTE_USER_LASTNAME
+ LookupUserAttr displayname REMOTE_USER_FULLNAME
+ LookupUserAttr domainname REMOTE_USER_DOMAIN
+
+ LookupUserGroups REMOTE_USER_GROUPS ":"
+ LookupDbusTimeout 5000
+ </LocationMatch>
+ external-auth-remote-user-conf: |
+ RequestHeader unset X_REMOTE_USER
+
+ RequestHeader set X_REMOTE_USER %{REMOTE_USER}e env=REMOTE_USER
+ RequestHeader set X_EXTERNAL_AUTH_ERROR %{EXTERNAL_AUTH_ERROR}e env=EXTERNAL_AUTH_ERROR
+ RequestHeader set X_REMOTE_USER_EMAIL %{REMOTE_USER_EMAIL}e env=REMOTE_USER_EMAIL
+ RequestHeader set X_REMOTE_USER_FIRSTNAME %{REMOTE_USER_FIRSTNAME}e env=REMOTE_USER_FIRSTNAME
+ RequestHeader set X_REMOTE_USER_LASTNAME %{REMOTE_USER_LASTNAME}e env=REMOTE_USER_LASTNAME
+ RequestHeader set X_REMOTE_USER_FULLNAME %{REMOTE_USER_FULLNAME}e env=REMOTE_USER_FULLNAME
+ RequestHeader set X_REMOTE_USER_GROUPS %{REMOTE_USER_GROUPS}e env=REMOTE_USER_GROUPS
+ RequestHeader set X_REMOTE_USER_DOMAIN %{REMOTE_USER_DOMAIN}e env=REMOTE_USER_DOMAIN
- apiVersion: v1
kind: ConfigMap
metadata:
name: "${HTTPD_SERVICE_NAME}-auth-configs"
data:
auth-type: internal
+ auth-kerberos-realms: undefined
auth-configuration.conf: |
# External Authentication Configuration File
#
@@ -203,15 +359,15 @@ objects:
- name: cloudforms
image: "${FRONTEND_APPLICATION_IMG_NAME}:${FRONTEND_APPLICATION_IMG_TAG}"
livenessProbe:
- tcpSocket:
- port: 80
+ exec:
+ command:
+ - pidof
+ - MIQ Server
initialDelaySeconds: 480
timeoutSeconds: 3
readinessProbe:
- httpGet:
- path: "/"
+ tcpSocket:
port: 80
- scheme: HTTP
initialDelaySeconds: 200
timeoutSeconds: 3
ports:
@@ -239,6 +395,11 @@ objects:
secretKeyRef:
name: "${NAME}-secrets"
key: v2-key
+ - name: APPLICATION_ADMIN_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: "${NAME}-secrets"
+ key: admin-password
- name: ANSIBLE_ADMIN_PASSWORD
valueFrom:
secretKeyRef:
@@ -611,6 +772,20 @@ objects:
selector:
name: httpd
- apiVersion: v1
+ kind: Service
+ metadata:
+ name: "${HTTPD_DBUS_API_SERVICE_NAME}"
+ annotations:
+ description: Exposes the httpd server dbus api
+ service.alpha.openshift.io/dependencies: '[{"name":"${NAME}","namespace":"","kind":"Service"}]'
+ spec:
+ ports:
+ - name: http-dbus-api
+ port: 8080
+ targetPort: 8080
+ selector:
+ name: httpd
+- apiVersion: v1
kind: DeploymentConfig
metadata:
name: "${HTTPD_SERVICE_NAME}"
@@ -644,6 +819,9 @@ objects:
image: "${HTTPD_IMG_NAME}:${HTTPD_IMG_TAG}"
ports:
- containerPort: 80
+ protocol: TCP
+ - containerPort: 8080
+ protocol: TCP
livenessProbe:
exec:
command:
@@ -673,6 +851,11 @@ objects:
configMapKeyRef:
name: "${HTTPD_SERVICE_NAME}-auth-configs"
key: auth-type
+ - name: HTTPD_AUTH_KERBEROS_REALMS
+ valueFrom:
+ configMapKeyRef:
+ name: "${HTTPD_SERVICE_NAME}-auth-configs"
+ key: auth-kerberos-realms
lifecycle:
postStart:
exec:
@@ -718,6 +901,11 @@ parameters:
displayName: Application Database Region
description: Database region that will be used for application.
value: '0'
+- name: APPLICATION_ADMIN_PASSWORD
+ displayName: Application Admin Password
+ required: true
+ description: Admin password that will be set on the application.
+ value: smartvm
- name: ANSIBLE_DATABASE_NAME
displayName: Ansible PostgreSQL database name
required: true
@@ -842,7 +1030,7 @@ parameters:
- name: POSTGRESQL_IMG_NAME
displayName: PostgreSQL Image Name
description: This is the PostgreSQL image name requested to deploy.
- value: brew-pulp-docker01.web.prod.ext.phx2.redhat.com:8888/cloudforms46/cfme-openshift-postgresql
+ value: registry.access.redhat.com/cloudforms46-beta/cfme-openshift-postgresql
- name: POSTGRESQL_IMG_TAG
displayName: PostgreSQL Image Tag
description: This is the PostgreSQL image tag/version requested to deploy.
@@ -850,7 +1038,7 @@ parameters:
- name: MEMCACHED_IMG_NAME
displayName: Memcached Image Name
description: This is the Memcached image name requested to deploy.
- value: brew-pulp-docker01.web.prod.ext.phx2.redhat.com:8888/cloudforms46/cfme-openshift-memcached
+ value: registry.access.redhat.com/cloudforms46-beta/cfme-openshift-memcached
- name: MEMCACHED_IMG_TAG
displayName: Memcached Image Tag
description: This is the Memcached image tag/version requested to deploy.
@@ -858,11 +1046,11 @@ parameters:
- name: FRONTEND_APPLICATION_IMG_NAME
displayName: Frontend Application Image Name
description: This is the Frontend Application image name requested to deploy.
- value: brew-pulp-docker01.web.prod.ext.phx2.redhat.com:8888/cloudforms46/cfme-openshift-app-ui
+ value: registry.access.redhat.com/cloudforms46-beta/cfme-openshift-app-ui
- name: BACKEND_APPLICATION_IMG_NAME
displayName: Backend Application Image Name
description: This is the Backend Application image name requested to deploy.
- value: brew-pulp-docker01.web.prod.ext.phx2.redhat.com:8888/cloudforms46/cfme-openshift-app
+ value: registry.access.redhat.com/cloudforms46-beta/cfme-openshift-app
- name: FRONTEND_APPLICATION_IMG_TAG
displayName: Front end Application Image Tag
description: This is the CloudForms Frontend Application image tag/version requested to deploy.
@@ -874,7 +1062,7 @@ parameters:
- name: ANSIBLE_IMG_NAME
displayName: Ansible Image Name
description: This is the Ansible image name requested to deploy.
- value: brew-pulp-docker01.web.prod.ext.phx2.redhat.com:8888/cloudforms46/cfme-openshift-embedded-ansible
+ value: registry.access.redhat.com/cloudforms46-beta/cfme-openshift-embedded-ansible
- name: ANSIBLE_IMG_TAG
displayName: Ansible Image Tag
description: This is the Ansible image tag/version requested to deploy.
@@ -907,10 +1095,15 @@ parameters:
displayName: Apache httpd Service Name
description: The name of the OpenShift Service exposed for the httpd container.
value: httpd
+- name: HTTPD_DBUS_API_SERVICE_NAME
+ required: true
+ displayName: Apache httpd DBus API Service Name
+ description: The name of httpd dbus api service.
+ value: httpd-dbus-api
- name: HTTPD_IMG_NAME
displayName: Apache httpd Image Name
description: This is the httpd image name requested to deploy.
- value: brew-pulp-docker01.web.prod.ext.phx2.redhat.com:8888/cloudforms46/cfme-openshift-httpd
+ value: registry.access.redhat.com/cloudforms46-beta/cfme-openshift-httpd
- name: HTTPD_IMG_TAG
displayName: Apache httpd Image Tag
description: This is the httpd image tag/version requested to deploy.
diff --git a/roles/openshift_master/tasks/upgrade/rpm_upgrade.yml b/roles/openshift_master/tasks/upgrade/rpm_upgrade.yml
index 7870f43e2..4564f33dd 100644
--- a/roles/openshift_master/tasks/upgrade/rpm_upgrade.yml
+++ b/roles/openshift_master/tasks/upgrade/rpm_upgrade.yml
@@ -8,8 +8,10 @@
# TODO: If the sdn package isn't already installed this will install it, we
# should fix that
-- name: Upgrade master packages
- package: name={{ master_pkgs | join(',') }} state=present
+- name: Upgrade master packages - yum
+ command:
+ yum install -y {{ master_pkgs | join(' ') }} \
+ {{ ' --exclude *' ~ openshift_service_type ~ '*3.9*' if openshift_release | version_compare('3.9','<') else '' }}
vars:
master_pkgs:
- "{{ openshift_service_type }}{{ openshift_pkg_version | default('') }}"
@@ -17,6 +19,21 @@
- "{{ openshift_service_type }}-node{{ openshift_pkg_version | default('') }}"
- "{{ openshift_service_type }}-sdn-ovs{{ openshift_pkg_version | default('') }}"
- "{{ openshift_service_type }}-clients{{ openshift_pkg_version | default('') }}"
- - "tuned-profiles-{{ openshift_service_type }}-node{{ openshift_pkg_version | default('') }}"
register: result
until: result is succeeded
+ when: ansible_pkg_mgr == 'yum'
+
+- name: Upgrade master packages - dnf
+ dnf:
+ name: "{{ master_pkgs | join(',') }}"
+ state: present
+ vars:
+ master_pkgs:
+ - "{{ openshift_service_type }}{{ openshift_pkg_version }}"
+ - "{{ openshift_service_type }}-master{{ openshift_pkg_version }}"
+ - "{{ openshift_service_type }}-node{{ openshift_pkg_version }}"
+ - "{{ openshift_service_type }}-sdn-ovs{{ openshift_pkg_version }}"
+ - "{{ openshift_service_type }}-clients{{ openshift_pkg_version }}"
+ register: result
+ until: result is succeeded
+ when: ansible_pkg_mgr == 'dnf'
diff --git a/roles/openshift_metrics/tasks/install_metrics.yaml b/roles/openshift_metrics/tasks/install_metrics.yaml
index 0866fe0d2..0dd5d1621 100644
--- a/roles/openshift_metrics/tasks/install_metrics.yaml
+++ b/roles/openshift_metrics/tasks/install_metrics.yaml
@@ -74,10 +74,10 @@
- name: Add metrics route information to web console asset config
include_role:
name: openshift_web_console
- tasks_from: update_asset_config.yml
+ tasks_from: update_console_config.yml
vars:
- asset_config_edits:
- - key: metricsPublicURL
+ console_config_edits:
+ - key: clusterInfo#metricsPublicURL
value: "https://{{ openshift_metrics_hawkular_hostname}}/hawkular/metrics"
when: openshift_web_console_install | default(true) | bool
diff --git a/roles/openshift_metrics/tasks/oc_apply.yaml b/roles/openshift_metrics/tasks/oc_apply.yaml
index 8ccfb7192..30fdde94c 100644
--- a/roles/openshift_metrics/tasks/oc_apply.yaml
+++ b/roles/openshift_metrics/tasks/oc_apply.yaml
@@ -16,7 +16,7 @@
apply -f {{ file_name }}
-n {{namespace}}
register: generation_apply
- failed_when: "'error' in generation_apply.stderr"
+ failed_when: "'error' in generation_apply.stderr or (generation_apply.rc | int != 0)"
changed_when: no
- name: Determine change status of {{file_content.kind}} {{file_content.metadata.name}}
@@ -28,5 +28,5 @@
register: version_changed
vars:
init_version: "{{ (generation_init is defined) | ternary(generation_init.stdout, '0') }}"
- failed_when: "'error' in version_changed.stderr"
+ failed_when: "'error' in version_changed.stderr or version_changed.rc | int != 0"
changed_when: version_changed.stdout | int > init_version | int
diff --git a/roles/openshift_metrics/tasks/uninstall_metrics.yaml b/roles/openshift_metrics/tasks/uninstall_metrics.yaml
index 610c7b4e5..1664e9975 100644
--- a/roles/openshift_metrics/tasks/uninstall_metrics.yaml
+++ b/roles/openshift_metrics/tasks/uninstall_metrics.yaml
@@ -19,13 +19,13 @@
clusterrolebinding/hawkular-metrics
changed_when: delete_metrics.stdout != 'No resources found'
-# Update asset config in openshift-web-console namespace
-- name: Remove metrics route information from web console asset config
+# Update the web config in openshift-web-console namespace
+- name: Remove metrics route information from the web console config
include_role:
name: openshift_web_console
- tasks_from: update_asset_config.yml
+ tasks_from: update_console_config.yml
vars:
- asset_config_edits:
- - key: metricsPublicURL
+ console_config_edits:
+ - key: clusterInfo#metricsPublicURL
value: ""
when: openshift_web_console_install | default(true) | bool
diff --git a/roles/openshift_node/defaults/main.yml b/roles/openshift_node/defaults/main.yml
index c1fab4382..5864d3c03 100644
--- a/roles/openshift_node/defaults/main.yml
+++ b/roles/openshift_node/defaults/main.yml
@@ -48,6 +48,12 @@ openshift_node_kubelet_args_dict:
cloud-config:
- "{{ openshift_config_base ~ '/cloudprovider/gce.conf' }}"
node-labels: "{{ l_node_kubelet_node_labels }}"
+ azure:
+ cloud-provider:
+ - azure
+ cloud-config:
+ - "{{ openshift_config_base ~ '/cloudprovider/azure.conf' }}"
+ node-labels: "{{ l_node_kubelet_node_labels }}"
undefined:
node-labels: "{{ l_node_kubelet_node_labels }}"
@@ -71,6 +77,18 @@ r_openshift_node_use_firewalld: "{{ os_firewall_use_firewalld | default(False) }
l_is_node_system_container: "{{ (openshift_use_node_system_container | default(openshift_use_system_containers | default(false)) | bool) }}"
+openshift_node_syscon_auth_mounts_l:
+- type: bind
+ source: "{{ oreg_auth_credentials_path }}"
+ destination: "/root/.docker"
+ options:
+ - ro
+
+# If we need to add new mounts in the future, or the user wants to mount data.
+# This should be in the same format as auth_mounts_l above.
+openshift_node_syscon_add_mounts_l: []
+
+
openshift_deployment_type: "{{ openshift_deployment_type | default('origin') }}"
openshift_node_image_dict:
diff --git a/roles/openshift_node/tasks/node_system_container.yml b/roles/openshift_node/tasks/node_system_container.yml
index 06b879050..008f209d7 100644
--- a/roles/openshift_node/tasks/node_system_container.yml
+++ b/roles/openshift_node/tasks/node_system_container.yml
@@ -14,4 +14,23 @@
- "DNS_DOMAIN={{ openshift.common.dns_domain }}"
- "DOCKER_SERVICE={{ openshift_docker_service_name }}.service"
- "MASTER_SERVICE={{ openshift_service_type }}.service"
+ - 'ADDTL_MOUNTS={{ l_node_syscon_add_mounts2 }}'
state: latest
+ vars:
+ # We need to evaluate some variables here to ensure
+ # l_bind_docker_reg_auth is evaluated after registry_auth.yml has been
+ # processed.
+
+ # Determine if we want to include auth credentials mount.
+ l_node_syscon_auth_mounts_l: "{{ l_bind_docker_reg_auth | ternary(openshift_node_syscon_auth_mounts_l,[]) }}"
+
+ # Join any user-provided mounts and auth_mounts into a combined list.
+ l_node_syscon_add_mounts_l: "{{ openshift_node_syscon_add_mounts_l | union(l_node_syscon_auth_mounts_l) }}"
+
+ # We must prepend a ',' here to ensure the value is inserted properly into an
+ # existing json list in the container's config.json
+ # lib_utils_oo_l_of_d_to_csv is a custom filter plugin in roles/lib_utils/oo_filters.py
+ l_node_syscon_add_mounts: ",{{ l_node_syscon_add_mounts_l | lib_utils_oo_l_of_d_to_csv }}"
+ # if we have just a ',' then both mount lists were empty, we don't want to add
+ # anything to config.json
+ l_node_syscon_add_mounts2: "{{ (l_node_syscon_add_mounts != ',') | bool | ternary(l_node_syscon_add_mounts,'') }}"
diff --git a/roles/openshift_node/tasks/upgrade/config_changes.yml b/roles/openshift_node/tasks/upgrade/config_changes.yml
index 721656117..dd9183382 100644
--- a/roles/openshift_node/tasks/upgrade/config_changes.yml
+++ b/roles/openshift_node/tasks/upgrade/config_changes.yml
@@ -21,6 +21,12 @@
path: "/var/lib/dockershim/sandbox/"
state: absent
+# https://bugzilla.redhat.com/show_bug.cgi?id=1518912
+- name: Clean up IPAM data
+ file:
+ path: "/var/lib/cni/networks/openshift-sdn/"
+ state: absent
+
# Disable Swap Block (pre)
- block:
- name: Remove swap entries from /etc/fstab
diff --git a/roles/openshift_node/templates/node.yaml.v1.j2 b/roles/openshift_node/templates/node.yaml.v1.j2
index 5f2a94ea2..7d817463c 100644
--- a/roles/openshift_node/templates/node.yaml.v1.j2
+++ b/roles/openshift_node/templates/node.yaml.v1.j2
@@ -32,7 +32,7 @@ masterClientConnectionOverrides:
contentType: application/vnd.kubernetes.protobuf
burst: 200
qps: 100
-masterKubeConfig: system:node:{{ openshift.common.hostname }}.kubeconfig
+masterKubeConfig: system:node:{{ openshift.common.hostname | lower }}.kubeconfig
{% if openshift_node_use_openshift_sdn | bool %}
networkPluginName: {{ openshift_node_sdn_network_plugin_name }}
{% endif %}
diff --git a/roles/openshift_node_certificates/tasks/main.yml b/roles/openshift_node_certificates/tasks/main.yml
index 5f73f3bdc..13d9fd718 100644
--- a/roles/openshift_node_certificates/tasks/main.yml
+++ b/roles/openshift_node_certificates/tasks/main.yml
@@ -18,9 +18,9 @@
stat:
path: "{{ openshift.common.config_base }}/node/{{ item }}"
with_items:
- - "system:node:{{ openshift.common.hostname }}.crt"
- - "system:node:{{ openshift.common.hostname }}.key"
- - "system:node:{{ openshift.common.hostname }}.kubeconfig"
+ - "system:node:{{ openshift.common.hostname | lower }}.crt"
+ - "system:node:{{ openshift.common.hostname | lower }}.key"
+ - "system:node:{{ openshift.common.hostname | lower }}.kubeconfig"
- ca.crt
- server.key
- server.crt
@@ -59,16 +59,16 @@
--certificate-authority {{ legacy_ca_certificate }}
{% endfor %}
--certificate-authority={{ openshift_ca_cert }}
- --client-dir={{ openshift_generated_configs_dir }}/node-{{ hostvars[item].openshift.common.hostname }}
+ --client-dir={{ openshift_generated_configs_dir }}/node-{{ hostvars[item].openshift.common.hostname | lower }}
--groups=system:nodes
--master={{ hostvars[openshift_ca_host].openshift.master.api_url }}
--signer-cert={{ openshift_ca_cert }}
--signer-key={{ openshift_ca_key }}
--signer-serial={{ openshift_ca_serial }}
- --user=system:node:{{ hostvars[item].openshift.common.hostname }}
+ --user=system:node:{{ hostvars[item].openshift.common.hostname | lower }}
--expire-days={{ openshift_node_cert_expire_days }}
args:
- creates: "{{ openshift_generated_configs_dir }}/node-{{ hostvars[item].openshift.common.hostname }}"
+ creates: "{{ openshift_generated_configs_dir }}/node-{{ hostvars[item].openshift.common.hostname | lower }}"
with_items: "{{ hostvars
| lib_utils_oo_select_keys(groups['oo_nodes_to_config'])
| lib_utils_oo_collect(attribute='inventory_hostname', filters={'node_certs_missing':True}) }}"
@@ -78,16 +78,16 @@
- name: Generate the node server certificate
command: >
{{ hostvars[openshift_ca_host]['first_master_client_binary'] }} adm ca create-server-cert
- --cert={{ openshift_generated_configs_dir }}/node-{{ hostvars[item].openshift.common.hostname }}/server.crt
- --key={{ openshift_generated_configs_dir }}/node-{{ hostvars[item].openshift.common.hostname }}/server.key
+ --cert={{ openshift_generated_configs_dir }}/node-{{ hostvars[item].openshift.common.hostname | lower }}/server.crt
+ --key={{ openshift_generated_configs_dir }}/node-{{ hostvars[item].openshift.common.hostname | lower }}/server.key
--expire-days={{ openshift_node_cert_expire_days }}
--overwrite=true
- --hostnames={{ hostvars[item].openshift.common.hostname }},{{ hostvars[item].openshift.common.public_hostname }},{{ hostvars[item].openshift.common.ip }},{{ hostvars[item].openshift.common.public_ip }}
+ --hostnames={{ hostvars[item].openshift.common.hostname }},{{ hostvars[item].openshift.common.hostname | lower }},{{ hostvars[item].openshift.common.public_hostname }},{{ hostvars[item].openshift.common.public_hostname | lower }},{{ hostvars[item].openshift.common.ip }},{{ hostvars[item].openshift.common.public_ip }}
--signer-cert={{ openshift_ca_cert }}
--signer-key={{ openshift_ca_key }}
--signer-serial={{ openshift_ca_serial }}
args:
- creates: "{{ openshift_generated_configs_dir }}/node-{{ hostvars[item].openshift.common.hostname }}/server.crt"
+ creates: "{{ openshift_generated_configs_dir }}/node-{{ hostvars[item].openshift.common.hostname | lower }}/server.crt"
with_items: "{{ hostvars
| lib_utils_oo_select_keys(groups['oo_nodes_to_config'])
| lib_utils_oo_collect(attribute='inventory_hostname', filters={'node_certs_missing':True}) }}"
diff --git a/roles/openshift_node_certificates/vars/main.yml b/roles/openshift_node_certificates/vars/main.yml
index 17ad8106d..12a6d3f94 100644
--- a/roles/openshift_node_certificates/vars/main.yml
+++ b/roles/openshift_node_certificates/vars/main.yml
@@ -1,7 +1,7 @@
---
openshift_generated_configs_dir: "{{ openshift.common.config_base }}/generated-configs"
openshift_node_cert_dir: "{{ openshift.common.config_base }}/node"
-openshift_node_cert_subdir: "node-{{ openshift.common.hostname }}"
+openshift_node_cert_subdir: "node-{{ openshift.common.hostname | lower }}"
openshift_node_config_dir: "{{ openshift.common.config_base }}/node"
openshift_node_generated_config_dir: "{{ openshift_generated_configs_dir }}/{{ openshift_node_cert_subdir }}"
diff --git a/roles/openshift_openstack/templates/heat_stack.yaml.j2 b/roles/openshift_openstack/templates/heat_stack.yaml.j2
index 1be5d3a62..8e7c6288a 100644
--- a/roles/openshift_openstack/templates/heat_stack.yaml.j2
+++ b/roles/openshift_openstack/templates/heat_stack.yaml.j2
@@ -523,7 +523,7 @@ resources:
floating_network:
if:
- no_floating
- - null
+ - ''
- {{ openshift_openstack_external_network_name }}
{% if openshift_openstack_provider_network_name %}
attach_float_net: false
@@ -589,8 +589,13 @@ resources:
secgrp:
- { get_resource: lb-secgrp }
- { get_resource: common-secgrp }
-{% if not openshift_openstack_provider_network_name %}
- floating_network: {{ openshift_openstack_external_network_name }}
+ floating_network:
+ if:
+ - no_floating
+ - ''
+ - {{ openshift_openstack_external_network_name }}
+{% if openshift_openstack_provider_network_name %}
+ attach_float_net: false
{% endif %}
volume_size: {{ openshift_openstack_lb_volume_size }}
{% if not openshift_openstack_provider_network_name %}
@@ -655,7 +660,7 @@ resources:
floating_network:
if:
- no_floating
- - null
+ - ''
- {{ openshift_openstack_external_network_name }}
{% if openshift_openstack_provider_network_name %}
attach_float_net: false
@@ -725,7 +730,7 @@ resources:
floating_network:
if:
- no_floating
- - null
+ - ''
- {{ openshift_openstack_external_network_name }}
{% if openshift_openstack_provider_network_name %}
attach_float_net: false
@@ -792,8 +797,13 @@ resources:
{% endif %}
- { get_resource: infra-secgrp }
- { get_resource: common-secgrp }
-{% if not openshift_openstack_provider_network_name %}
- floating_network: {{ openshift_openstack_external_network_name }}
+ floating_network:
+ if:
+ - no_floating
+ - ''
+ - {{ openshift_openstack_external_network_name }}
+{% if openshift_openstack_provider_network_name %}
+ attach_float_net: false
{% endif %}
volume_size: {{ openshift_openstack_infra_volume_size }}
{% if openshift_openstack_infra_server_group_policies|length > 0 %}
diff --git a/roles/openshift_openstack/templates/heat_stack_server.yaml.j2 b/roles/openshift_openstack/templates/heat_stack_server.yaml.j2
index 1e73c9e1c..29b09f3c9 100644
--- a/roles/openshift_openstack/templates/heat_stack_server.yaml.j2
+++ b/roles/openshift_openstack/templates/heat_stack_server.yaml.j2
@@ -102,13 +102,11 @@ parameters:
label: Attach-float-net
description: A switch for floating network port connection
-{% if not openshift_openstack_provider_network_name %}
floating_network:
type: string
default: ''
label: Floating network
description: Network to allocate floating IP from
-{% endif %}
availability_zone:
type: string
diff --git a/roles/openshift_persistent_volumes/tasks/pv.yml b/roles/openshift_persistent_volumes/tasks/pv.yml
index ef9ab7f5f..865269b7a 100644
--- a/roles/openshift_persistent_volumes/tasks/pv.yml
+++ b/roles/openshift_persistent_volumes/tasks/pv.yml
@@ -13,5 +13,5 @@
--config={{ mktemp.stdout }}/admin.kubeconfig
register: pv_create_output
when: persistent_volumes | length > 0
- failed_when: ('already exists' not in pv_create_output.stderr) and ('created' not in pv_create_output.stdout)
+ failed_when: "('already exists' not in pv_create_output.stderr) and ('created' not in pv_create_output.stdout) and pv_create_output.rc != 0"
changed_when: ('created' in pv_create_output.stdout)
diff --git a/roles/openshift_persistent_volumes/tasks/pvc.yml b/roles/openshift_persistent_volumes/tasks/pvc.yml
index 2c5519192..6c12d128c 100644
--- a/roles/openshift_persistent_volumes/tasks/pvc.yml
+++ b/roles/openshift_persistent_volumes/tasks/pvc.yml
@@ -13,5 +13,5 @@
--config={{ mktemp.stdout }}/admin.kubeconfig
register: pvc_create_output
when: persistent_volume_claims | length > 0
- failed_when: ('already exists' not in pvc_create_output.stderr) and ('created' not in pvc_create_output.stdout)
+ failed_when: "('already exists' not in pvc_create_output.stderr) and ('created' not in pvc_create_output.stdout) and pvc_create_output.rc != 0"
changed_when: ('created' in pvc_create_output.stdout)
diff --git a/roles/openshift_provisioners/tasks/oc_apply.yaml b/roles/openshift_provisioners/tasks/oc_apply.yaml
index a4ce53eae..27c8a4b81 100644
--- a/roles/openshift_provisioners/tasks/oc_apply.yaml
+++ b/roles/openshift_provisioners/tasks/oc_apply.yaml
@@ -15,7 +15,7 @@
apply -f {{ file_name }}
-n {{ namespace }}
register: generation_apply
- failed_when: "'error' in generation_apply.stderr"
+ failed_when: "'error' in generation_apply.stderr or generation_apply.rc != 0"
changed_when: no
- name: Determine change status of {{file_content.kind}} {{file_content.metadata.name}}
@@ -36,7 +36,7 @@
delete -f {{ file_name }}
-n {{ namespace }}
register: generation_delete
- failed_when: "'error' in generation_delete.stderr"
+ failed_when: "'error' in generation_delete.stderr or generation_delete.rc != 0"
changed_when: generation_delete.rc == 0
when: generation_apply.rc != 0
@@ -46,6 +46,6 @@
apply -f {{ file_name }}
-n {{ namespace }}
register: generation_apply
- failed_when: "'error' in generation_apply.stderr"
+ failed_when: "'error' in generation_apply.stderr or generation_apply.rc | int != 0"
changed_when: generation_apply.rc == 0
when: generation_apply.rc != 0
diff --git a/roles/openshift_service_catalog/defaults/main.yml b/roles/openshift_service_catalog/defaults/main.yml
index 7c848cb12..15ca9838c 100644
--- a/roles/openshift_service_catalog/defaults/main.yml
+++ b/roles/openshift_service_catalog/defaults/main.yml
@@ -1,6 +1,7 @@
---
openshift_service_catalog_remove: false
openshift_service_catalog_nodeselector: {"openshift-infra": "apiserver"}
+openshift_service_catalog_async_bindings_enabled: false
openshift_use_openshift_sdn: True
# os_sdn_network_plugin_name: "{% if openshift_use_openshift_sdn %}redhat/openshift-ovs-subnet{% else %}{% endif %}"
diff --git a/roles/openshift_service_catalog/templates/controller_manager.j2 b/roles/openshift_service_catalog/templates/controller_manager.j2
index 137222f04..c61e05f73 100644
--- a/roles/openshift_service_catalog/templates/controller_manager.j2
+++ b/roles/openshift_service_catalog/templates/controller_manager.j2
@@ -8,7 +8,7 @@ spec:
selector:
matchLabels:
app: controller-manager
- strategy:
+ updateStrategy:
rollingUpdate:
maxUnavailable: 1
type: RollingUpdate
@@ -38,6 +38,10 @@ spec:
- "5m"
- --feature-gates
- OriginatingIdentity=true
+{% if openshift_service_catalog_async_bindings_enabled | bool %}
+ - --feature-gates
+ - AsyncBindingOperations=true
+{% endif %}
image: {{ openshift_service_catalog_image_prefix }}service-catalog:{{ openshift_service_catalog_image_version }}
command: ["/usr/bin/service-catalog"]
imagePullPolicy: Always
diff --git a/roles/openshift_version/tasks/check_available_rpms.yml b/roles/openshift_version/tasks/check_available_rpms.yml
index bdbc63d27..fea0daf77 100644
--- a/roles/openshift_version/tasks/check_available_rpms.yml
+++ b/roles/openshift_version/tasks/check_available_rpms.yml
@@ -1,7 +1,7 @@
---
- name: Get available {{ openshift_service_type}} version
repoquery:
- name: "{{ openshift_service_type}}"
+ name: "{{ openshift_service_type}}{{ '-' ~ openshift_release ~ '*' if openshift_release is defined else '' }}"
ignore_excluders: true
register: rpm_results
diff --git a/roles/openshift_version/tasks/first_master_containerized_version.yml b/roles/openshift_version/tasks/first_master_containerized_version.yml
index e02a75eab..3ed1d2cfe 100644
--- a/roles/openshift_version/tasks/first_master_containerized_version.yml
+++ b/roles/openshift_version/tasks/first_master_containerized_version.yml
@@ -7,6 +7,7 @@
when:
- openshift_image_tag is defined
- openshift_version is not defined
+ - not (openshift_version_reinit | default(false))
- name: Set containerized version to configure if openshift_release specified
set_fact:
@@ -20,7 +21,7 @@
docker run --rm {{ openshift_cli_image }}:latest version
register: cli_image_version
when:
- - openshift_version is not defined
+ - openshift_version is not defined or openshift_version_reinit | default(false)
- not openshift_use_crio_only
# Origin latest = pre-release version (i.e. v1.3.0-alpha.1-321-gb095e3a)
@@ -34,7 +35,7 @@
- set_fact:
openshift_version: "{{ cli_image_version.stdout_lines[0].split(' ')[1].split('-')[0][1:] }}"
- when: openshift_version is not defined
+ when: openshift_version is not defined or openshift_version_reinit | default(false)
# If we got an openshift_version like "3.2", lookup the latest 3.2 container version
# and use that value instead.
diff --git a/roles/openshift_version/tasks/first_master_rpm_version.yml b/roles/openshift_version/tasks/first_master_rpm_version.yml
index 264baca65..5d92f90c6 100644
--- a/roles/openshift_version/tasks/first_master_rpm_version.yml
+++ b/roles/openshift_version/tasks/first_master_rpm_version.yml
@@ -6,6 +6,7 @@
when:
- openshift_pkg_version is defined
- openshift_version is not defined
+ - not (openshift_version_reinit | default(false))
# These tasks should only be run against masters and nodes
- name: Set openshift_version for rpm installation
@@ -13,4 +14,7 @@
- set_fact:
openshift_version: "{{ rpm_results.results.versions.available_versions.0 }}"
- when: openshift_version is not defined
+ when: openshift_version is not defined or ( openshift_version_reinit | default(false) )
+- set_fact:
+ openshift_pkg_version: "-{{ rpm_results.results.versions.available_versions.0 }}"
+ when: openshift_version_reinit | default(false)
diff --git a/roles/openshift_version/tasks/masters_and_nodes.yml b/roles/openshift_version/tasks/masters_and_nodes.yml
index fbeb22d8b..eddd5ff42 100644
--- a/roles/openshift_version/tasks/masters_and_nodes.yml
+++ b/roles/openshift_version/tasks/masters_and_nodes.yml
@@ -6,9 +6,12 @@
include_tasks: check_available_rpms.yml
- name: Fail if rpm version and docker image version are different
fail:
- msg: "OCP rpm version {{ openshift_rpm_version }} is different from OCP image version {{ openshift_version }}"
+ msg: "OCP rpm version {{ rpm_results.results.versions.available_versions.0 }} is different from OCP image version {{ openshift_version }}"
# Both versions have the same string representation
- when: rpm_results.results.versions.available_versions.0 != openshift_version
+ when:
+ - openshift_version not in rpm_results.results.versions.available_versions.0
+ - openshift_version_reinit | default(false)
+
# block when
when: not openshift_is_atomic | bool
diff --git a/roles/openshift_web_console/defaults/main.yml b/roles/openshift_web_console/defaults/main.yml
index 4f395398c..c747f73a8 100644
--- a/roles/openshift_web_console/defaults/main.yml
+++ b/roles/openshift_web_console/defaults/main.yml
@@ -1,3 +1,2 @@
---
-# TODO: This is temporary and will be updated to use taints and tolerations so that the console runs on the masters
-openshift_web_console_nodeselector: {"region":"infra"}
+openshift_web_console_nodeselector: "{{ openshift_hosted_infra_selector | default('region=infra') | map_from_pairs }}"
diff --git a/roles/openshift_web_console/tasks/install.yml b/roles/openshift_web_console/tasks/install.yml
index 12916961b..cc5eef47d 100644
--- a/roles/openshift_web_console/tasks/install.yml
+++ b/roles/openshift_web_console/tasks/install.yml
@@ -21,43 +21,123 @@
node_selector:
- ""
-- name: Make temp directory for asset config files
+- name: Make temp directory for web console templates
command: mktemp -d /tmp/console-ansible-XXXXXX
register: mktemp
changed_when: False
-- name: Copy asset config template to temp directory
+- name: Copy admin client config
+ command: >
+ cp {{ openshift.common.config_base }}/master//admin.kubeconfig {{ mktemp.stdout }}/admin.kubeconfig
+ changed_when: false
+
+- name: Copy web console templates to temp directory
copy:
src: "{{ __console_files_location }}/{{ item }}"
dest: "{{ mktemp.stdout }}/{{ item }}"
with_items:
- "{{ __console_template_file }}"
+ - "{{ __console_rbac_file }}"
- "{{ __console_config_file }}"
-- name: Update asset config properties
- yedit:
- src: "{{ mktemp.stdout }}/{{ __console_config_file }}"
- edits:
- - key: logoutURL
- value: "{{ openshift.master.logout_url | default('') }}"
- - key: publicURL
- # Must have a trailing slash
- value: "{{ openshift.master.public_console_url }}/"
- - key: masterPublicURL
- value: "{{ openshift.master.public_api_url }}"
+# Check if an existing webconsole-config config map exists. If so, use those
+# contents so we don't overwrite changes.
+- name: Read the existing web console config map
+ oc_configmap:
+ namespace: openshift-web-console
+ name: webconsole-config
+ state: list
+ register: webconsole_config_map
+
+- set_fact:
+ existing_config_map_data: "{{ webconsole_config_map.results.results[0].data | default({}) }}"
+
+- name: Copy the existing web console config to temp directory
+ copy:
+ content: "{{ existing_config_map_data['webconsole-config.yaml'] }}"
+ dest: "{{ mktemp.stdout }}/{{ __console_config_file }}"
+ when: existing_config_map_data['webconsole-config.yaml'] is defined
+
+# Generate a new config when a config map is not defined.
+- when: existing_config_map_data['webconsole-config.yaml'] is not defined
+ block:
+ # Migrate the previous master-config.yaml asset config if it exists into the new
+ # web console config config map.
+ - name: Read existing assetConfig in master-config.yaml
+ slurp:
+ src: "{{ openshift.common.config_base }}/master/master-config.yaml"
+ register: master_config_output
+
+ - set_fact:
+ config_to_migrate: "{{ master_config_output.content | b64decode | from_yaml }}"
+
+ # Update properties in the config template based on inventory vars when the
+ # asset config does not exist.
+ - name: Set web console config properties from inventory variables
+ yedit:
+ src: "{{ mktemp.stdout }}/{{ __console_config_file }}"
+ edits:
+ - key: clusterInfo#consolePublicURL
+ # Must have a trailing slash
+ value: "{{ openshift.master.public_console_url }}/"
+ - key: clusterInfo#masterPublicURL
+ value: "{{ openshift.master.public_api_url }}"
+ - key: clusterInfo#logoutPublicURL
+ value: "{{ openshift.master.logout_url | default('') }}"
+ - key: features#inactivityTimeoutMinutes
+ value: "{{ openshift_web_console_inactivity_timeout_minutes | default(0) }}"
+ - key: features#clusterResourceOverridesEnabled
+ value: "{{ openshift_web_console_cluster_resource_overrides_enabled | default(false) }}"
+ - key: extensions#scriptURLs
+ value: "{{ openshift_web_console_extension_script_urls | default([]) }}"
+ - key: extensions#stylesheetURLs
+ value: "{{ openshift_web_console_extension_stylesheet_urls | default([]) }}"
+ - key: extensions#properties
+ value: "{{ openshift_web_console_extension_properties | default({}) }}"
+ separator: '#'
+ state: present
+ when: config_to_migrate.assetConfig is not defined
+
+ - name: Migrate assetConfig from master-config.yaml
+ yedit:
+ src: "{{ mktemp.stdout }}/{{ __console_config_file }}"
+ edits:
+ - key: clusterInfo#consolePublicURL
+ value: "{{ config_to_migrate.assetConfig.publicURL }}"
+ - key: clusterInfo#masterPublicURL
+ value: "{{ config_to_migrate.assetConfig.masterPublicURL }}"
+ - key: clusterInfo#logoutPublicURL
+ value: "{{ config_to_migrate.assetConfig.logoutURL | default('') }}"
+ - key: clusterInfo#metricsPublicURL
+ value: "{{ config_to_migrate.assetConfig.metricsPublicURL | default('') }}"
+ - key: clusterInfo#loggingPublicURL
+ value: "{{ config_to_migrate.assetConfig.loggingPublicURL | default('') }}"
+ - key: servingInfo#maxRequestsInFlight
+ value: "{{ config_to_migrate.assetConfig.servingInfo.maxRequestsInFlight | default(0) }}"
+ - key: servingInfo#requestTimeoutSeconds
+ value: "{{ config_to_migrate.assetConfig.servingInfo.requestTimeoutSeconds | default(0) }}"
+ separator: '#'
+ state: present
+ when: config_to_migrate.assetConfig is defined
- slurp:
src: "{{ mktemp.stdout }}/{{ __console_config_file }}"
- register: config
+ register: updated_console_config
+
+- name: Reconcile with the web console RBAC file
+ shell: >
+ {{ openshift_client_binary }} process -f "{{ mktemp.stdout }}/{{ __console_rbac_file }}" --config={{ mktemp.stdout }}/admin.kubeconfig
+ | {{ openshift_client_binary }} auth reconcile --config={{ mktemp.stdout }}/admin.kubeconfig -f -
-- name: Apply template file
+- name: Apply the web console template file
shell: >
{{ openshift_client_binary }} process -f "{{ mktemp.stdout }}/{{ __console_template_file }}"
- --param API_SERVER_CONFIG="{{ config['content'] | b64decode }}"
+ --param API_SERVER_CONFIG="{{ updated_console_config['content'] | b64decode }}"
--param IMAGE="{{ openshift_web_console_prefix }}{{ openshift_web_console_image_name }}:{{ openshift_web_console_version }}"
--param NODE_SELECTOR={{ openshift_web_console_nodeselector | to_json | quote }}
--param REPLICA_COUNT="{{ openshift_web_console_replica_count }}"
- | {{ openshift_client_binary }} apply -f -
+ --config={{ mktemp.stdout }}/admin.kubeconfig
+ | {{ openshift_client_binary }} apply --config={{ mktemp.stdout }}/admin.kubeconfig -f -
- name: Verify that the web console is running
command: >
diff --git a/roles/openshift_web_console/tasks/rollout_console.yml b/roles/openshift_web_console/tasks/rollout_console.yml
new file mode 100644
index 000000000..75682ba1d
--- /dev/null
+++ b/roles/openshift_web_console/tasks/rollout_console.yml
@@ -0,0 +1,20 @@
+---
+- name: Check if console deployment exists
+ oc_obj:
+ kind: deployments
+ name: webconsole
+ namespace: openshift-web-console
+ state: list
+ register: console_deployment
+
+# There's currently no command to trigger a rollout for a k8s deployment
+# without changing the pod spec. Add an annotation to force a rollout.
+- name: Rollout updated web console deployment
+ oc_edit:
+ kind: deployments
+ name: webconsole
+ namespace: openshift-web-console
+ separator: '#'
+ content:
+ spec#template#metadata#annotations#installer-triggered-rollout: "{{ ansible_date_time.iso8601_micro }}"
+ when: console_deployment.results.results.0 | length > 0
diff --git a/roles/openshift_web_console/tasks/update_asset_config.yml b/roles/openshift_web_console/tasks/update_asset_config.yml
deleted file mode 100644
index 0992b32e1..000000000
--- a/roles/openshift_web_console/tasks/update_asset_config.yml
+++ /dev/null
@@ -1,68 +0,0 @@
----
-# This task updates asset config values in the webconsole-config config map in
-# the openshift-web-console namespace. The values to set are pased in the
-# variable `asset_config_edits`, which is an array of objects with `key` and
-# `value` properties in the same format as `yedit` module `edits`. Only
-# properties passed are updated.
-#
-# Note that this triggers a redeployment on the console and a brief downtime
-# since it uses a `Recreate` strategy.
-#
-# Example usage:
-#
-# - include_role:
-# name: openshift_web_console
-# tasks_from: update_asset_config.yml
-# vars:
-# asset_config_edits:
-# - key: loggingPublicURL
-# value: "https://{{ openshift_logging_kibana_hostname }}"
-# when: openshift_web_console_install | default(true) | bool
-
-- name: Read web console config map
- oc_configmap:
- namespace: openshift-web-console
- name: webconsole-config
- state: list
- register: webconsole_config
-
-- name: Make temp directory
- command: mktemp -d /tmp/console-ansible-XXXXXX
- register: mktemp
- changed_when: False
-
-- name: Copy asset config to temp file
- copy:
- content: "{{webconsole_config.results.results[0].data['webconsole-config.yaml']}}"
- dest: "{{ mktemp.stdout }}/webconsole-config.yaml"
-
-- name: Change asset config properties
- yedit:
- src: "{{ mktemp.stdout }}/webconsole-config.yaml"
- edits: "{{asset_config_edits}}"
-
-- name: Update web console config map
- oc_configmap:
- namespace: openshift-web-console
- name: webconsole-config
- state: present
- from_file:
- webconsole-config.yaml: "{{ mktemp.stdout }}/webconsole-config.yaml"
-
-- name: Remove temp directory
- file:
- state: absent
- name: "{{ mktemp.stdout }}"
- changed_when: False
-
-# There's currently no command to trigger a rollout for a k8s deployment
-# without changing the pod spec. Add an annotation to force a rollout after
-# the config map has been edited.
-- name: Rollout updated web console deployment
- oc_edit:
- kind: deployments
- name: webconsole
- namespace: openshift-web-console
- separator: '#'
- content:
- spec#template#metadata#annotations#installer-triggered-rollout: "{{ ansible_date_time.iso8601_micro }}"
diff --git a/roles/openshift_web_console/tasks/update_console_config.yml b/roles/openshift_web_console/tasks/update_console_config.yml
new file mode 100644
index 000000000..967222ea4
--- /dev/null
+++ b/roles/openshift_web_console/tasks/update_console_config.yml
@@ -0,0 +1,67 @@
+---
+# This task updates asset config values in the webconsole-config config map in
+# the openshift-web-console namespace. The values to set are pased in the
+# variable `console_config_edits`, which is an array of objects with `key` and
+# `value` properties in the same format as `yedit` module `edits`. Only
+# properties passed are updated. The separator for nested properties is `#`.
+#
+# Note that this triggers a redeployment on the console and a brief downtime
+# since it uses a `Recreate` strategy.
+#
+# Example usage:
+#
+# - include_role:
+# name: openshift_web_console
+# tasks_from: update_console_config.yml
+# vars:
+# console_config_edits:
+# - key: clusterInfo#loggingPublicURL
+# value: "https://{{ openshift_logging_kibana_hostname }}"
+# when: openshift_web_console_install | default(true) | bool
+
+- name: Read the existing web console config map
+ oc_configmap:
+ namespace: openshift-web-console
+ name: webconsole-config
+ state: list
+ register: webconsole_config_map
+
+- set_fact:
+ existing_config_map_data: "{{ webconsole_config_map.results.results[0].data | default({}) }}"
+
+- when: existing_config_map_data['webconsole-config.yaml'] is defined
+ block:
+ - name: Make temp directory
+ command: mktemp -d /tmp/console-ansible-XXXXXX
+ register: mktemp_console
+ changed_when: False
+
+ - name: Copy the existing web console config to temp directory
+ copy:
+ content: "{{ existing_config_map_data['webconsole-config.yaml'] }}"
+ dest: "{{ mktemp_console.stdout }}/webconsole-config.yaml"
+
+ - name: Change web console config properties
+ yedit:
+ src: "{{ mktemp_console.stdout }}/webconsole-config.yaml"
+ edits: "{{console_config_edits}}"
+ separator: '#'
+ state: present
+
+ - name: Update web console config map
+ oc_configmap:
+ namespace: openshift-web-console
+ name: webconsole-config
+ state: present
+ from_file:
+ webconsole-config.yaml: "{{ mktemp_console.stdout }}/webconsole-config.yaml"
+ register: update_console_config_map
+
+ - name: Remove temp directory
+ file:
+ state: absent
+ name: "{{ mktemp_console.stdout }}"
+ changed_when: False
+
+ - include_tasks: rollout_console.yml
+ when: update_console_config_map.changed | bool
diff --git a/roles/openshift_web_console/vars/default_images.yml b/roles/openshift_web_console/vars/default_images.yml
index 7adb8a0d0..42d331ac5 100644
--- a/roles/openshift_web_console/vars/default_images.yml
+++ b/roles/openshift_web_console/vars/default_images.yml
@@ -1,4 +1,4 @@
---
-__openshift_web_console_prefix: "docker.io/openshift/"
+__openshift_web_console_prefix: "docker.io/openshift/origin-"
__openshift_web_console_version: "latest"
-__openshift_web_console_image_name: "origin-web-console"
+__openshift_web_console_image_name: "web-console"
diff --git a/roles/openshift_web_console/vars/main.yml b/roles/openshift_web_console/vars/main.yml
index 80bc56a17..e91048e38 100644
--- a/roles/openshift_web_console/vars/main.yml
+++ b/roles/openshift_web_console/vars/main.yml
@@ -2,4 +2,5 @@
__console_files_location: "../../../files/origin-components/"
__console_template_file: "console-template.yaml"
+__console_rbac_file: "console-rbac-template.yaml"
__console_config_file: "console-config.yaml"
diff --git a/roles/openshift_web_console/vars/openshift-enterprise.yml b/roles/openshift_web_console/vars/openshift-enterprise.yml
index 721ac1d27..375c22067 100644
--- a/roles/openshift_web_console/vars/openshift-enterprise.yml
+++ b/roles/openshift_web_console/vars/openshift-enterprise.yml
@@ -1,4 +1,4 @@
---
-__openshift_web_console_prefix: "registry.access.redhat.com/openshift3/"
+__openshift_web_console_prefix: "registry.access.redhat.com/openshift3/ose-"
__openshift_web_console_version: "v3.9"
-__openshift_web_console_image_name: "ose-web-console"
+__openshift_web_console_image_name: "web-console"
diff --git a/roles/os_firewall/tasks/firewalld.yml b/roles/os_firewall/tasks/firewalld.yml
index 4eae31596..fa933da51 100644
--- a/roles/os_firewall/tasks/firewalld.yml
+++ b/roles/os_firewall/tasks/firewalld.yml
@@ -2,7 +2,9 @@
- name: Fail - Firewalld is not supported on Atomic Host
fail:
msg: "Firewalld is not supported on Atomic Host"
- when: r_os_firewall_is_atomic | bool
+ when:
+ - r_os_firewall_is_atomic | bool
+ - not openshift_enable_unsupported_configurations | default(false)
- name: Install firewalld packages
package:
@@ -10,6 +12,7 @@
state: present
register: result
until: result is succeeded
+ when: not r_os_firewall_is_atomic | bool
- name: Ensure iptables services are not enabled
systemd:
diff --git a/roles/template_service_broker/defaults/main.yml b/roles/template_service_broker/defaults/main.yml
index c32872d24..3465832cc 100644
--- a/roles/template_service_broker/defaults/main.yml
+++ b/roles/template_service_broker/defaults/main.yml
@@ -3,4 +3,4 @@
template_service_broker_remove: False
template_service_broker_install: True
openshift_template_service_broker_namespaces: ['openshift']
-template_service_broker_selector: { "region": "infra" }
+template_service_broker_selector: "{{ openshift_hosted_infra_selector | default('region=infra') | map_from_pairs }}"
diff --git a/roles/template_service_broker/tasks/install.yml b/roles/template_service_broker/tasks/install.yml
index 604e94602..4e6ad2ae5 100644
--- a/roles/template_service_broker/tasks/install.yml
+++ b/roles/template_service_broker/tasks/install.yml
@@ -22,6 +22,11 @@
register: mktemp
changed_when: False
+- name: Copy admin client config
+ command: >
+ cp {{ openshift.common.config_base }}/master//admin.kubeconfig {{ mktemp.stdout }}/admin.kubeconfig
+ changed_when: false
+
- copy:
src: "{{ __tsb_files_location }}/{{ item }}"
dest: "{{ mktemp.stdout }}/{{ item }}"
@@ -43,16 +48,18 @@
- name: Apply template file
shell: >
- {{ openshift_client_binary }} process -f "{{ mktemp.stdout }}/{{ __tsb_template_file }}"
+ {{ openshift_client_binary }} process --config={{ mktemp.stdout }}/admin.kubeconfig
+ -f "{{ mktemp.stdout }}/{{ __tsb_template_file }}"
--param API_SERVER_CONFIG="{{ config['content'] | b64decode }}"
--param IMAGE="{{ template_service_broker_prefix }}{{ template_service_broker_image_name }}:{{ template_service_broker_version }}"
--param NODE_SELECTOR={{ template_service_broker_selector | to_json | quote }}
- | {{ openshift_client_binary }} apply -f -
+ | {{ openshift_client_binary }} apply --config={{ mktemp.stdout }}/admin.kubeconfig -f -
# reconcile with rbac
- name: Reconcile with RBAC file
shell: >
- {{ openshift_client_binary }} process -f "{{ mktemp.stdout }}/{{ __tsb_rbac_file }}" | {{ openshift_client_binary }} auth reconcile -f -
+ {{ openshift_client_binary }} process --config={{ mktemp.stdout }}/admin.kubeconfig -f "{{ mktemp.stdout }}/{{ __tsb_rbac_file }}"
+ | {{ openshift_client_binary }} auth reconcile --config={{ mktemp.stdout }}/admin.kubeconfig -f -
# Check that the TSB is running
- name: Verify that TSB is running
@@ -79,9 +86,15 @@
# Register with broker
- name: Register TSB with broker
shell: >
- {{ openshift_client_binary }} process -f "{{ mktemp.stdout }}/{{ __tsb_broker_file }}" --param CA_BUNDLE="{{ __ca_bundle.content }}" | {{ openshift_client_binary }} apply -f -
+ {{ openshift_client_binary }} process --config={{ mktemp.stdout }}/admin.kubeconfig -f "{{ mktemp.stdout }}/{{ __tsb_broker_file }}" --param CA_BUNDLE="{{ __ca_bundle.content }}" | {{ openshift_client_binary }} apply --config={{ mktemp.stdout }}/admin.kubeconfig -f -
- file:
state: absent
name: "{{ mktemp.stdout }}"
changed_when: False
+
+- name: Rollout console so it discovers the template service broker is installed
+ include_role:
+ name: openshift_web_console
+ tasks_from: rollout_console.yml
+ when: openshift_web_console_install | default(true) | bool
diff --git a/roles/template_service_broker/tasks/remove.yml b/roles/template_service_broker/tasks/remove.yml
index db1b558e4..48dc1327e 100644
--- a/roles/template_service_broker/tasks/remove.yml
+++ b/roles/template_service_broker/tasks/remove.yml
@@ -3,6 +3,11 @@
register: mktemp
changed_when: False
+- name: Copy admin client config
+ command: >
+ cp {{ openshift.common.config_base }}/master//admin.kubeconfig {{ mktemp.stdout }}/admin.kubeconfig
+ changed_when: false
+
- copy:
src: "{{ __tsb_files_location }}/{{ item }}"
dest: "{{ mktemp.stdout }}/{{ item }}"
@@ -12,11 +17,11 @@
- name: Delete TSB broker
shell: >
- {{ openshift_client_binary }} process -f "{{ mktemp.stdout }}/{{ __tsb_broker_file }}" | {{ openshift_client_binary }} delete --ignore-not-found -f -
+ {{ openshift_client_binary }} process --config={{ mktemp.stdout }}/admin.kubeconfig -f "{{ mktemp.stdout }}/{{ __tsb_broker_file }}" | {{ openshift_client_binary }} delete --config={{ mktemp.stdout }}/admin.kubeconfig --ignore-not-found -f -
- name: Delete TSB objects
shell: >
- {{ openshift_client_binary }} process -f "{{ mktemp.stdout }}/{{ __tsb_template_file }}" | {{ openshift_client_binary }} delete --ignore-not-found -f -
+ {{ openshift_client_binary }} process --config={{ mktemp.stdout }}/admin.kubeconfig -f "{{ mktemp.stdout }}/{{ __tsb_template_file }}" | {{ openshift_client_binary }} delete --config={{ mktemp.stdout }}/admin.kubeconfig --ignore-not-found -f -
- name: empty out tech preview extension file for service console UI
copy:
@@ -31,3 +36,9 @@
state: absent
name: "{{ mktemp.stdout }}"
changed_when: False
+
+- name: Rollout console so it discovers the template service broker is removed
+ include_role:
+ name: openshift_web_console
+ tasks_from: rollout_console.yml
+ when: openshift_web_console_install | default(true) | bool
diff --git a/roles/template_service_broker/vars/default_images.yml b/roles/template_service_broker/vars/default_images.yml
index 662d65d9f..dc164a4db 100644
--- a/roles/template_service_broker/vars/default_images.yml
+++ b/roles/template_service_broker/vars/default_images.yml
@@ -1,4 +1,4 @@
---
-__template_service_broker_prefix: "docker.io/openshift/"
+__template_service_broker_prefix: "docker.io/openshift/origin-"
__template_service_broker_version: "latest"
-__template_service_broker_image_name: "origin-template-service-broker"
+__template_service_broker_image_name: "template-service-broker"
diff --git a/roles/template_service_broker/vars/openshift-enterprise.yml b/roles/template_service_broker/vars/openshift-enterprise.yml
index 16a08e72f..b65b97691 100644
--- a/roles/template_service_broker/vars/openshift-enterprise.yml
+++ b/roles/template_service_broker/vars/openshift-enterprise.yml
@@ -1,4 +1,4 @@
---
-__template_service_broker_prefix: "registry.access.redhat.com/openshift3/"
+__template_service_broker_prefix: "registry.access.redhat.com/openshift3/ose-"
__template_service_broker_version: "v3.7"
-__template_service_broker_image_name: "ose-template-service-broker"
+__template_service_broker_image_name: "template-service-broker"
diff --git a/roles/tuned/tasks/main.yml b/roles/tuned/tasks/main.yml
index 4a28d47b2..5129f4471 100644
--- a/roles/tuned/tasks/main.yml
+++ b/roles/tuned/tasks/main.yml
@@ -28,7 +28,12 @@
when: item.state == 'file'
- name: Make tuned use the recommended tuned profile on restart
- file: path=/etc/tuned/active_profile state=absent
+ file:
+ path: '{{ item }}'
+ state: absent
+ with_items:
+ - /etc/tuned/active_profile
+ - /etc/tuned/profile_mode
- name: Restart tuned service
systemd: