summaryrefslogtreecommitdiffstats
path: root/roles/openshift_logging
diff options
context:
space:
mode:
Diffstat (limited to 'roles/openshift_logging')
-rw-r--r--roles/openshift_logging/README.md227
-rw-r--r--roles/openshift_logging/defaults/main.yml179
-rw-r--r--roles/openshift_logging/files/generate-jks.sh178
-rw-r--r--roles/openshift_logging/files/server-tls.json5
-rw-r--r--roles/openshift_logging/filter_plugins/openshift_logging.py77
-rw-r--r--roles/openshift_logging/handlers/main.yml30
-rw-r--r--roles/openshift_logging/library/openshift_logging_facts.py343
-rw-r--r--roles/openshift_logging/meta/main.yaml16
-rw-r--r--roles/openshift_logging/tasks/annotate_ops_projects.yaml17
-rw-r--r--roles/openshift_logging/tasks/delete_logging.yaml114
-rw-r--r--roles/openshift_logging/tasks/generate_certs.yaml148
-rw-r--r--roles/openshift_logging/tasks/generate_jks.yaml88
-rw-r--r--roles/openshift_logging/tasks/generate_pems.yaml37
-rw-r--r--roles/openshift_logging/tasks/install_logging.yaml282
-rw-r--r--roles/openshift_logging/tasks/main.yaml44
-rw-r--r--roles/openshift_logging/tasks/procure_server_certs.yaml58
-rw-r--r--roles/openshift_logging/tasks/procure_shared_key.yaml25
-rw-r--r--roles/openshift_logging/tasks/update_master_config.yaml11
-rw-r--r--roles/openshift_logging/templates/jks_pod.j228
-rw-r--r--roles/openshift_logging/templates/signing.conf.j2103
-rw-r--r--roles/openshift_logging/vars/default_images.yml3
-rw-r--r--roles/openshift_logging/vars/main.yaml10
-rw-r--r--roles/openshift_logging/vars/openshift-enterprise.yml3
23 files changed, 2026 insertions, 0 deletions
diff --git a/roles/openshift_logging/README.md b/roles/openshift_logging/README.md
new file mode 100644
index 000000000..69eb9283d
--- /dev/null
+++ b/roles/openshift_logging/README.md
@@ -0,0 +1,227 @@
+## openshift_logging Role
+
+### Please note this role is still a work in progress
+
+This role is used for installing the Aggregated Logging stack. It should be run against
+a single host, it will create any missing certificates and API objects that the current
+[logging deployer](https://github.com/openshift/origin-aggregated-logging/tree/master/deployer) does.
+
+This role requires that the control host it is run on has Java installed as part of keystore
+generation for Elasticsearch (it uses JKS) as well as openssl to sign certificates.
+
+As part of the installation, it is recommended that you add the Fluentd node selector label
+to the list of persisted [node labels](https://docs.openshift.org/latest/install_config/install/advanced_install.html#configuring-node-host-labels).
+
+### Required vars:
+
+- `openshift_logging_install_logging`: When `True` the `openshift_logging` role will install Aggregated Logging.
+
+When `openshift_logging_install_logging` is set to `False` the `openshift_logging` role will uninstall Aggregated Logging.
+
+### Optional vars:
+- `openshift_logging_purge_logging`: When `openshift_logging_install_logging` is set to 'False' to trigger uninstalation and `openshift_logging_purge_logging` is set to 'True', it will completely and irreversibly remove all logging persistent data including PVC. Defaults to 'False'.
+- `openshift_logging_image_prefix`: The prefix for the logging images to use. Defaults to 'docker.io/openshift/origin-'.
+- `openshift_logging_curator_image_prefix`: Setting the image prefix for Curator image. Defaults to `openshift_logging_image_prefix`.
+- `openshift_logging_elasticsearch_image_prefix`: Setting the image prefix for Elasticsearch image. Defaults to `openshift_logging_image_prefix`.
+- `openshift_logging_fluentd_image_prefix`: Setting the image prefix for Fluentd image. Defaults to `openshift_logging_image_prefix`.
+- `openshift_logging_kibana_image_prefix`: Setting the image prefix for Kibana image. Defaults to `openshift_logging_image_prefix`.
+- `openshift_logging_kibana_proxy_image_prefix`: Setting the image prefix for Kibana proxy image. Defaults to `openshift_logging_image_prefix`.
+- `openshift_logging_mux_image_prefix`: Setting the image prefix for Mux image. Defaults to `openshift_logging_image_prefix`.
+- `openshift_logging_image_version`: The image version for the logging images to use. Defaults to 'latest'.
+- `openshift_logging_curator_image_version`: Setting the image version for Curator image. Defaults to `openshift_logging_image_version`.
+- `openshift_logging_elasticsearch_image_version`: Setting the image version for Elasticsearch image. Defaults to `openshift_logging_image_version`.
+- `openshift_logging_fluentd_image_version`: Setting the image version for Fluentd image. Defaults to `openshift_logging_image_version`.
+- `openshift_logging_kibana_image_version`: Setting the image version for Kibana image. Defaults to `openshift_logging_image_version`.
+- `openshift_logging_kibana_proxy_image_version`: Setting the image version for Kibana proxy image. Defaults to `openshift_logging_image_version`.
+- `openshift_logging_mux_image_version`: Setting the image version for Mux image. Defaults to `openshift_logging_image_version`.
+- `openshift_logging_use_ops`: If 'True', set up a second ES and Kibana cluster for infrastructure logs. Defaults to 'False'.
+- `openshift_logging_master_url`: The URL for the Kubernetes master, this does not need to be public facing but should be accessible from within the cluster. Defaults to 'https://kubernetes.default.svc.{{openshift.common.dns_domain}}'.
+- `openshift_logging_master_public_url`: The public facing URL for the Kubernetes master, this is used for Authentication redirection. Defaults to 'https://{{openshift.common.public_hostname}}:{{openshift.master.api_port}}'.
+- `openshift_logging_namespace`: The namespace that Aggregated Logging will be installed in. Defaults to 'logging'.
+- `openshift_logging_curator_default_days`: The default minimum age (in days) Curator uses for deleting log records. Defaults to '30'.
+- `openshift_logging_curator_run_hour`: The hour of the day that Curator will run at. Defaults to '0'.
+- `openshift_logging_curator_run_minute`: The minute of the hour that Curator will run at. Defaults to '0'.
+- `openshift_logging_curator_run_timezone`: The timezone that Curator uses for figuring out its run time. Defaults to 'UTC'.
+- `openshift_logging_curator_script_log_level`: The script log level for Curator. Defaults to 'INFO'.
+- `openshift_logging_curator_log_level`: The log level for the Curator process. Defaults to 'ERROR'.
+- `openshift_logging_curator_cpu_limit`: The amount of CPU to allocate to Curator. Default is '100m'.
+- `openshift_logging_curator_memory_limit`: The amount of memory to allocate to Curator. Unset if not specified.
+- `openshift_logging_curator_nodeselector`: A map of labels (e.g. {"node":"infra","region":"west"} to select the nodes where the curator pod will land.
+- `openshift_logging_image_pull_secret`: The name of an existing pull secret to link to the logging service accounts
+
+- `openshift_logging_kibana_hostname`: The Kibana hostname. Defaults to 'kibana.example.com'.
+- `openshift_logging_kibana_cpu_limit`: The amount of CPU to allocate to Kibana or unset if not specified.
+- `openshift_logging_kibana_memory_limit`: The amount of memory to allocate to Kibana or unset if not specified.
+- `openshift_logging_kibana_proxy_debug`: When "True", set the Kibana Proxy log level to DEBUG. Defaults to 'false'.
+- `openshift_logging_kibana_proxy_cpu_limit`: The amount of CPU to allocate to Kibana proxy or unset if not specified.
+- `openshift_logging_kibana_proxy_memory_limit`: The amount of memory to allocate to Kibana proxy or unset if not specified.
+- `openshift_logging_kibana_replica_count`: The number of replicas Kibana should be scaled up to. Defaults to 1.
+- `openshift_logging_kibana_nodeselector`: A map of labels (e.g. {"node":"infra","region":"west"} to select the nodes where the pod will land.
+- `openshift_logging_kibana_edge_term_policy`: Insecure Edge Termination Policy. Defaults to Redirect.
+
+- `openshift_logging_fluentd_nodeselector`: The node selector that the Fluentd daemonset uses to determine where to deploy to. Defaults to '"logging-infra-fluentd": "true"'.
+- `openshift_logging_fluentd_cpu_limit`: The CPU limit for Fluentd pods. Defaults to '100m'.
+- `openshift_logging_fluentd_memory_limit`: The memory limit for Fluentd pods. Defaults to '512Mi'.
+- `openshift_logging_fluentd_use_journal`: *DEPRECATED - DO NOT USE* Fluentd will automatically detect whether or not Docker is using the journald log driver.
+- `openshift_logging_fluentd_journal_read_from_head`: If empty, Fluentd will use its internal default, which is false.
+- `openshift_logging_fluentd_hosts`: List of nodes that should be labeled for Fluentd to be deployed to. Defaults to ['--all'].
+- `openshift_logging_fluentd_buffer_queue_limit`: Buffer queue limit for Fluentd. Defaults to 1024.
+- `openshift_logging_fluentd_buffer_size_limit`: Buffer chunk limit for Fluentd. Defaults to 1m.
+- `openshift_logging_fluentd_file_buffer_limit`: Fluentd will set the value to the file buffer limit. Defaults to '1Gi' per destination.
+
+- `openshift_logging_fluentd_audit_container_engine`: When `openshift_logging_fluentd_audit_container_engine` is set to `True`, the audit log of the container engine will be collected and stored in ES.
+- `openshift_logging_fluentd_audit_file`: Location of audit log file. The default is `/var/log/audit/audit.log`
+- `openshift_logging_fluentd_audit_pos_file`: Location of fluentd in_tail position file for the audit log file. The default is `/var/log/audit/audit.log.pos`
+
+- `openshift_logging_es_host`: The name of the ES service Fluentd should send logs to. Defaults to 'logging-es'.
+- `openshift_logging_es_port`: The port for the ES service Fluentd should sent its logs to. Defaults to '9200'.
+- `openshift_logging_es_ca`: The location of the ca Fluentd uses to communicate with its openshift_logging_es_host. Defaults to '/etc/fluent/keys/ca'.
+- `openshift_logging_es_client_cert`: The location of the client certificate Fluentd uses for openshift_logging_es_host. Defaults to '/etc/fluent/keys/cert'.
+- `openshift_logging_es_client_key`: The location of the client key Fluentd uses for openshift_logging_es_host. Defaults to '/etc/fluent/keys/key'.
+
+- `openshift_logging_es_cluster_size`: The number of ES cluster members. Defaults to '1'.
+- `openshift_logging_es_cpu_limit`: The amount of CPU limit for the ES cluster. Unused if not set
+- `openshift_logging_es_memory_limit`: The amount of RAM that should be assigned to ES. Defaults to '8Gi'.
+- `openshift_logging_es_log_appenders`: The list of rootLogger appenders for ES logs which can be: 'file', 'console'. Defaults to 'file'.
+- `openshift_logging_es_pv_selector`: A key/value map added to a PVC in order to select specific PVs. Defaults to 'None'.
+- `openshift_logging_es_pvc_dynamic`: Whether or not to add the dynamic PVC annotation for any generated PVCs. Defaults to 'False'.
+- `openshift_logging_es_pvc_size`: The requested size for the ES PVCs, when not provided the role will not generate any PVCs. Defaults to '""'.
+- `openshift_logging_es_pvc_prefix`: The prefix for the generated PVCs. Defaults to 'logging-es'.
+- `openshift_logging_es_recover_after_time`: The amount of time ES will wait before it tries to recover. Defaults to '5m'.
+- `openshift_logging_es_storage_group`: The storage group used for ES. Defaults to '65534'.
+- `openshift_logging_es_nodeselector`: A map of labels (e.g. {"node":"infra","region":"west"} to select the nodes where the pod will land.
+- `openshift_logging_es_number_of_shards`: The number of primary shards for every new index created in ES. Defaults to '1'.
+- `openshift_logging_es_number_of_replicas`: The number of replica shards per primary shard for every new index. Defaults to '0'.
+
+- `openshift_logging_install_eventrouter`: Coupled with `openshift_logging_install_logging`. When both are 'True', eventrouter will be installed. When both are 'False', eventrouter will be uninstalled.
+Other combinations will keep the eventrouter untouched.
+
+Detailed eventrouter configuration can be found in
+- `roles/openshift_logging_eventrouter/README.md`
+
+When `openshift_logging_use_ops` is `True`, there are some additional vars. These work the
+same as above for their non-ops counterparts, but apply to the OPS cluster instance:
+- `openshift_logging_es_ops_host`: logging-es-ops
+- `openshift_logging_es_ops_port`: 9200
+- `openshift_logging_es_ops_ca`: /etc/fluent/keys/ca
+- `openshift_logging_es_ops_client_cert`: /etc/fluent/keys/cert
+- `openshift_logging_es_ops_client_key`: /etc/fluent/keys/key
+- `openshift_logging_es_ops_cluster_size`: 1
+- `openshift_logging_es_ops_cpu_limit`: The amount of CPU limit for the ES cluster. Unused if not set
+- `openshift_logging_es_ops_memory_limit`: 8Gi
+- `openshift_logging_es_ops_pvc_dynamic`: False
+- `openshift_logging_es_ops_pvc_size`: ""
+- `openshift_logging_es_ops_pvc_prefix`: logging-es-ops
+- `openshift_logging_es_ops_recover_after_time`: 5m
+- `openshift_logging_es_ops_storage_group`: 65534
+- `openshift_logging_kibana_ops_hostname`: The Operations Kibana hostname. Defaults to 'kibana-ops.example.com'.
+- `openshift_logging_kibana_ops_cpu_limit`: The amount of CPU to allocate to Kibana or unset if not specified.
+- `openshift_logging_kibana_ops_memory_limit`: The amount of memory to allocate to Kibana or unset if not specified.
+- `openshift_logging_kibana_ops_proxy_cpu_limit`: The amount of CPU to allocate to Kibana proxy or unset if not specified.
+- `openshift_logging_kibana_ops_proxy_memory_limit`: The amount of memory to allocate to Kibana proxy or unset if not specified.
+- `openshift_logging_kibana_ops_replica_count`: The number of replicas Kibana ops should be scaled up to. Defaults to 1.
+
+Elasticsearch can be exposed for external clients outside of the cluster.
+- `openshift_logging_es_allow_external`: True (default is False) - if this is
+ True, Elasticsearch will be exposed as a Route
+- `openshift_logging_es_hostname`: The external facing hostname to use for
+ the route and the TLS server certificate (default is "es." +
+ `openshift_master_default_subdomain`)
+- `openshift_logging_es_cert`: The location of the certificate Elasticsearch
+ uses for the external TLS server cert (default is a generated cert)
+- `openshift_logging_es_key`: The location of the key Elasticsearch
+ uses for the external TLS server cert (default is a generated key)
+- `openshift_logging_es_ca_ext`: The location of the CA cert for the cert
+ Elasticsearch uses for the external TLS server cert (default is the internal
+ CA)
+Elasticsearch OPS too, if using an OPS cluster:
+- `openshift_logging_es_ops_allow_external`: True (default is False) - if this is
+ True, Elasticsearch will be exposed as a Route
+- `openshift_logging_es_ops_hostname`: The external facing hostname to use for
+ the route and the TLS server certificate (default is "es-ops." +
+ `openshift_master_default_subdomain`)
+- `openshift_logging_es_ops_cert`: The location of the certificate Elasticsearch
+ uses for the external TLS server cert (default is a generated cert)
+- `openshift_logging_es_ops_key`: The location of the key Elasticsearch
+ uses for the external TLS server cert (default is a generated key)
+- `openshift_logging_es_ops_ca_ext`: The location of the CA cert for the cert
+ Elasticsearch uses for the external TLS server cert (default is the internal
+ CA)
+
+### mux - secure_forward listener service
+- `openshift_logging_use_mux`: Default `False`. If this is `True`, a service
+ called `mux` will be deployed. This service will act as a Fluentd
+ secure_forward forwarder for the node agent Fluentd daemonsets running in the
+ cluster. This can be used to reduce the number of connections to the
+ OpenShift API server, by using `mux` and configuring each node Fluentd to
+ send raw logs to mux and turn off the k8s metadata plugin. This requires the
+ use of `openshift_logging_mux_client_mode` (see below).
+- `openshift_logging_mux_allow_external`: Default `False`. If this is `True`,
+ the `mux` service will be deployed, and it will be configured to allow
+ Fluentd clients running outside of the cluster to send logs using
+ secure_forward. This allows OpenShift logging to be used as a central
+ logging service for clients other than OpenShift, or other OpenShift
+ clusters.
+- `openshift_logging_mux_client_mode`: Values - `minimal`, `maximal`.
+ Default is unset. Setting this value will cause the Fluentd node agent to
+ send logs to mux rather than directly to Elasticsearch. The value
+ `maximal` means that Fluentd will do as much processing as possible at the
+ node before sending the records to mux. This is the current recommended
+ way to use mux due to current scaling issues.
+ The value `minimal` means that Fluentd will do *no* processing at all, and
+ send the raw logs to mux for processing. We do not currently recommend using
+ this mode, and ansible will warn you about this.
+- `openshift_logging_mux_hostname`: Default is "mux." +
+ `openshift_master_default_subdomain`. This is the hostname *external*
+ clients will use to connect to mux, and will be used in the TLS server cert
+ subject.
+- `openshift_logging_mux_port`: 24284
+- `openshift_logging_mux_cpu_limit`: 100m
+- `openshift_logging_mux_memory_limit`: 512Mi
+- `openshift_logging_mux_default_namespaces`: Default `["mux-undefined"]` - the
+ first value in the list is the namespace to use for undefined projects,
+ followed by any additional namespaces to create by default - users will
+ typically not need to set this
+- `openshift_logging_mux_namespaces`: Default `[]` - additional namespaces to
+ create for _external_ mux clients to associate with their logs - users will
+ need to set this
+- `openshift_logging_mux_buffer_queue_limit`: Default `[1024]` - Buffer queue limit for Mux.
+- `openshift_logging_mux_buffer_size_limit`: Default `[1m]` - Buffer chunk limit for Mux.
+- `openshift_logging_mux_file_buffer_limit`: Default `[2Gi]` per destination - Mux will
+ set the value to the file buffer limit.
+- `openshift_logging_mux_file_buffer_storage_type`: Default `[emptydir]` - Storage
+ type for the file buffer. One of [`emptydir`, `pvc`, `hostmount`]
+
+- `openshift_logging_mux_file_buffer_pvc_size`: The requested size for the file buffer
+ PVC, when not provided the role will not generate any PVCs. Defaults to `4Gi`.
+- `openshift_logging_mux_file_buffer_pvc_dynamic`: Whether or not to add the dynamic
+ PVC annotation for any generated PVCs. Defaults to 'False'.
+- `openshift_logging_mux_file_buffer_pvc_pv_selector`: A key/value map added to a PVC
+ in order to select specific PVs. Defaults to 'None'.
+- `openshift_logging_mux_file_buffer_pvc_prefix`: The prefix for the generated PVCs.
+ Defaults to 'logging-mux'.
+- `openshift_logging_mux_file_buffer_storage_group`: The storage group used for Mux.
+ Defaults to '65534'.
+
+### remote syslog forwarding
+- `openshift_logging_fluentd_remote_syslog`: Set `true` to enable remote syslog forwarding, defaults to `false`
+- `openshift_logging_fluentd_remote_syslog_host`: Required, hostname or IP of remote syslog server
+- `openshift_logging_fluentd_remote_syslog_port`: Port of remote syslog server, defaults to `514`
+- `openshift_logging_fluentd_remote_syslog_severity`: Syslog severity level, defaults to `debug`
+- `openshift_logging_fluentd_remote_syslog_facility`: Syslog facility, defaults to `local0`
+- `openshift_logging_fluentd_remote_syslog_remove_tag_prefix`: Remove the prefix from the tag, defaults to `''` (empty)
+- `openshift_logging_fluentd_remote_syslog_tag_key`: If string specified, use this field from the record to set the key field on the syslog message
+- `openshift_logging_fluentd_remote_syslog_use_record`: Set `true` to use the severity and facility from the record, defaults to `false`
+- `openshift_logging_fluentd_remote_syslog_payload_key`: If string is specified, use this field from the record as the payload on the syslog message
+
+The corresponding openshift\_logging\_mux\_* parameters are below.
+
+- `openshift_logging_mux_remote_syslog`: Set `true` to enable remote syslog forwarding, defaults to `false`
+- `openshift_logging_mux_remote_syslog_host`: Required, hostname or IP of remote syslog server
+- `openshift_logging_mux_remote_syslog_port`: Port of remote syslog server, defaults to `514`
+- `openshift_logging_mux_remote_syslog_severity`: Syslog severity level, defaults to `debug`
+- `openshift_logging_mux_remote_syslog_facility`: Syslog facility, defaults to `local0`
+- `openshift_logging_mux_remote_syslog_remove_tag_prefix`: Remove the prefix from the tag, defaults to `''` (empty)
+- `openshift_logging_mux_remote_syslog_tag_key`: If string specified, use this field from the record to set the key field on the syslog message
+- `openshift_logging_mux_remote_syslog_use_record`: Set `true` to use the severity and facility from the record, defaults to `false`
+- `openshift_logging_mux_remote_syslog_payload_key`: If string is specified, use this field from the record as the payload on the syslog message
diff --git a/roles/openshift_logging/defaults/main.yml b/roles/openshift_logging/defaults/main.yml
new file mode 100644
index 000000000..6e7e2557f
--- /dev/null
+++ b/roles/openshift_logging/defaults/main.yml
@@ -0,0 +1,179 @@
+---
+openshift_logging_use_ops: False
+openshift_logging_master_url: "https://kubernetes.default.svc.{{ openshift.common.dns_domain }}"
+openshift_logging_master_public_url: "{{ 'https://' + openshift.common.public_hostname + ':' ~ (openshift_master_api_port | default('8443', true)) }}"
+openshift_logging_namespace: logging
+openshift_logging_nodeselector: null
+openshift_logging_labels: {}
+openshift_logging_label_key: ""
+openshift_logging_label_value: ""
+openshift_logging_install_logging: False
+
+openshift_logging_purge_logging: False
+openshift_logging_image_pull_secret: ""
+
+openshift_logging_curator_default_days: 30
+openshift_logging_curator_run_hour: 0
+openshift_logging_curator_run_minute: 0
+openshift_logging_curator_run_timezone: UTC
+openshift_logging_curator_script_log_level: INFO
+openshift_logging_curator_log_level: ERROR
+openshift_logging_curator_cpu_limit: 100m
+openshift_logging_curator_memory_limit: null
+openshift_logging_curator_nodeselector: {}
+
+openshift_logging_curator_ops_cpu_limit: 100m
+openshift_logging_curator_ops_memory_limit: null
+openshift_logging_curator_ops_nodeselector: {}
+
+openshift_logging_kibana_hostname: "{{ 'kibana.' ~ (openshift_master_default_subdomain | default('router.default.svc.cluster.local', true)) }}"
+openshift_logging_kibana_cpu_limit: null
+openshift_logging_kibana_memory_limit: 736Mi
+openshift_logging_kibana_proxy_debug: false
+openshift_logging_kibana_proxy_cpu_limit: null
+openshift_logging_kibana_proxy_memory_limit: 256Mi
+openshift_logging_kibana_replica_count: 1
+openshift_logging_kibana_edge_term_policy: Redirect
+
+openshift_logging_kibana_nodeselector: {}
+openshift_logging_kibana_ops_nodeselector: {}
+
+#The absolute path on the control node to the cert file to use
+#for the public facing kibana certs
+openshift_logging_kibana_cert: ""
+
+#The absolute path on the control node to the key file to use
+#for the public facing kibana certs
+openshift_logging_kibana_key: ""
+
+#The absolute path on the control node to the CA file to use
+#for the public facing kibana certs
+openshift_logging_kibana_ca: ""
+
+openshift_logging_kibana_ops_hostname: "{{ 'kibana-ops.' ~ (openshift_master_default_subdomain | default('router.default.svc.cluster.local', true)) }}"
+openshift_logging_kibana_ops_cpu_limit: null
+openshift_logging_kibana_ops_memory_limit: 736Mi
+openshift_logging_kibana_ops_proxy_debug: false
+openshift_logging_kibana_ops_proxy_cpu_limit: null
+openshift_logging_kibana_ops_proxy_memory_limit: 256Mi
+openshift_logging_kibana_ops_replica_count: 1
+
+#The absolute path on the control node to the cert file to use
+#for the public facing ops kibana certs
+openshift_logging_kibana_ops_cert: ""
+
+#The absolute path on the control node to the key file to use
+#for the public facing ops kibana certs
+openshift_logging_kibana_ops_key: ""
+
+#The absolute path on the control node to the CA file to use
+#for the public facing ops kibana certs
+openshift_logging_kibana_ops_ca: ""
+
+openshift_logging_fluentd_nodeselector: {'logging-infra-fluentd': 'true'}
+openshift_logging_fluentd_cpu_limit: 100m
+openshift_logging_fluentd_memory_limit: 512Mi
+openshift_logging_fluentd_journal_source: ""
+openshift_logging_fluentd_journal_read_from_head: ""
+openshift_logging_fluentd_hosts: ['--all']
+openshift_logging_fluentd_buffer_queue_limit: 1024
+openshift_logging_fluentd_buffer_size_limit: 1m
+
+openshift_logging_es_host: logging-es
+openshift_logging_es_port: 9200
+openshift_logging_es_ca: /etc/fluent/keys/ca
+openshift_logging_es_client_cert: /etc/fluent/keys/cert
+openshift_logging_es_client_key: /etc/fluent/keys/key
+openshift_logging_es_cluster_size: 1
+openshift_logging_es_cpu_limit: 1000m
+# the logging appenders for the root loggers to write ES logs. Valid values: 'file', 'console'
+openshift_logging_es_log_appenders: ['file']
+openshift_logging_es_memory_limit: "8Gi"
+openshift_logging_es_pv_selector: "{{ openshift_logging_storage_labels | default('') }}"
+openshift_logging_es_pvc_dynamic: "{{ openshift_logging_elasticsearch_pvc_dynamic | default(False) }}"
+openshift_logging_es_pvc_size: "{{ openshift_logging_elasticsearch_pvc_size | default('') }}"
+openshift_logging_es_pvc_prefix: "{{ openshift_logging_elasticsearch_pvc_prefix | default('logging-es') }}"
+openshift_logging_es_recover_after_time: 5m
+openshift_logging_es_storage_group: "65534"
+openshift_logging_es_nodeselector: {}
+# openshift_logging_es_config is a hash to be merged into the defaults for the elasticsearch.yaml
+openshift_logging_es_config: {}
+openshift_logging_es_number_of_shards: 1
+openshift_logging_es_number_of_replicas: 0
+
+# for exposing es to external (outside of the cluster) clients
+openshift_logging_es_allow_external: False
+openshift_logging_es_hostname: "{{ 'es.' ~ (openshift_master_default_subdomain | default('router.default.svc.cluster.local', true)) }}"
+
+#The absolute path on the control node to the cert file to use
+#for the public facing es certs
+openshift_logging_es_cert: ""
+
+#The absolute path on the control node to the key file to use
+#for the public facing es certs
+openshift_logging_es_key: ""
+
+#The absolute path on the control node to the CA file to use
+#for the public facing es certs
+openshift_logging_es_ca_ext: ""
+
+# allow cluster-admin or cluster-reader to view operations index
+openshift_logging_es_ops_allow_cluster_reader: False
+
+openshift_logging_es_ops_host: logging-es-ops
+openshift_logging_es_ops_port: 9200
+openshift_logging_es_ops_ca: /etc/fluent/keys/ca
+openshift_logging_es_ops_client_cert: /etc/fluent/keys/cert
+openshift_logging_es_ops_client_key: /etc/fluent/keys/key
+openshift_logging_es_ops_cluster_size: "{{ openshift_logging_elasticsearch_ops_cluster_size | default(1) }}"
+openshift_logging_es_ops_cpu_limit: 1000m
+openshift_logging_es_ops_memory_limit: "8Gi"
+openshift_logging_es_ops_pv_selector: "{{ openshift_loggingops_storage_labels | default('') }}"
+openshift_logging_es_ops_pvc_dynamic: "{{ openshift_logging_elasticsearch_ops_pvc_dynamic | default(False) }}"
+openshift_logging_es_ops_pvc_size: "{{ openshift_logging_elasticsearch_ops_pvc_size | default('') }}"
+openshift_logging_es_ops_pvc_prefix: "{{ openshift_logging_elasticsearch_ops_pvc_prefix | default('logging-es-ops') }}"
+openshift_logging_es_ops_recover_after_time: 5m
+openshift_logging_es_ops_storage_group: "65534"
+openshift_logging_es_ops_nodeselector: {}
+
+# for exposing es-ops to external (outside of the cluster) clients
+openshift_logging_es_ops_allow_external: False
+openshift_logging_es_ops_hostname: "{{ 'es-ops.' ~ (openshift_master_default_subdomain | default('router.default.svc.cluster.local', true)) }}"
+
+#The absolute path on the control node to the cert file to use
+#for the public facing es-ops certs
+openshift_logging_es_ops_cert: ""
+
+#The absolute path on the control node to the key file to use
+#for the public facing es-ops certs
+openshift_logging_es_ops_key: ""
+
+#The absolute path on the control node to the CA file to use
+#for the public facing es-ops certs
+openshift_logging_es_ops_ca_ext: ""
+
+# storage related defaults
+openshift_logging_storage_access_modes: ['ReadWriteOnce']
+
+# mux - secure_forward listener service
+openshift_logging_mux_allow_external: False
+openshift_logging_use_mux: "{{ openshift_logging_mux_allow_external | default(False) }}"
+openshift_logging_mux_hostname: "{{ 'mux.' ~ (openshift_master_default_subdomain | default('router.default.svc.cluster.local', true)) }}"
+openshift_logging_mux_port: 24284
+openshift_logging_mux_cpu_limit: 500m
+openshift_logging_mux_memory_limit: 1Gi
+# the namespace to use for undefined projects should come first, followed by any
+# additional namespaces to create by default - users will typically not need to set this
+openshift_logging_mux_default_namespaces: ["mux-undefined"]
+# extra namespaces to create for mux clients - users will need to set this
+openshift_logging_mux_namespaces: []
+
+# following can be uncommented to provide values for configmaps -- take care when providing file contents as it may cause your cluster to not operate correctly
+#es_logging_contents:
+#es_config_contents:
+#curator_config_contents:
+#fluentd_config_contents:
+#fluentd_throttle_contents:
+#fluentd_secureforward_contents:
+#fluentd_mux_config_contents:
+#fluentd_mux_secureforward_contents:
diff --git a/roles/openshift_logging/files/generate-jks.sh b/roles/openshift_logging/files/generate-jks.sh
new file mode 100644
index 000000000..b5ba7f9d1
--- /dev/null
+++ b/roles/openshift_logging/files/generate-jks.sh
@@ -0,0 +1,178 @@
+#! /bin/bash
+set -ex
+
+function usage() {
+ echo Usage: `basename $0` cert_directory [logging_namespace] 1>&2
+}
+
+function generate_JKS_chain() {
+ dir=${SCRATCH_DIR:-_output}
+ ADD_OID=$1
+ NODE_NAME=$2
+ CERT_NAMES=${3:-$NODE_NAME}
+ ks_pass=${KS_PASS:-kspass}
+ ts_pass=${TS_PASS:-tspass}
+ rm -rf $NODE_NAME
+
+ extension_names=""
+ for name in ${CERT_NAMES//,/ }; do
+ extension_names="${extension_names},dns:${name}"
+ done
+
+ if [ "$ADD_OID" = true ]; then
+ extension_names="${extension_names},oid:1.2.3.4.5.5"
+ fi
+
+ echo Generating keystore and certificate for node $NODE_NAME
+
+ keytool -genkey \
+ -alias $NODE_NAME \
+ -keystore $dir/$NODE_NAME.jks \
+ -keypass $ks_pass \
+ -storepass $ks_pass \
+ -keyalg RSA \
+ -keysize 2048 \
+ -validity 712 \
+ -dname "CN=$NODE_NAME, OU=OpenShift, O=Logging" \
+ -ext san=dns:localhost,ip:127.0.0.1"${extension_names}"
+
+ echo Generating certificate signing request for node $NODE_NAME
+
+ keytool -certreq \
+ -alias $NODE_NAME \
+ -keystore $dir/$NODE_NAME.jks \
+ -storepass $ks_pass \
+ -file $dir/$NODE_NAME.csr \
+ -keyalg rsa \
+ -dname "CN=$NODE_NAME, OU=OpenShift, O=Logging" \
+ -ext san=dns:localhost,ip:127.0.0.1"${extension_names}"
+
+ echo Sign certificate request with CA
+
+ openssl ca \
+ -in $dir/$NODE_NAME.csr \
+ -notext \
+ -out $dir/$NODE_NAME.crt \
+ -config $dir/signing.conf \
+ -extensions v3_req \
+ -batch \
+ -extensions server_ext
+
+ echo "Import back to keystore (including CA chain)"
+
+ keytool \
+ -import \
+ -file $dir/ca.crt \
+ -keystore $dir/$NODE_NAME.jks \
+ -storepass $ks_pass \
+ -noprompt -alias sig-ca
+
+ keytool \
+ -import \
+ -file $dir/$NODE_NAME.crt \
+ -keystore $dir/$NODE_NAME.jks \
+ -storepass $ks_pass \
+ -noprompt \
+ -alias $NODE_NAME
+
+ echo All done for $NODE_NAME
+}
+
+function generate_JKS_client_cert() {
+ NODE_NAME="$1"
+ ks_pass=${KS_PASS:-kspass}
+ ts_pass=${TS_PASS:-tspass}
+ dir=${SCRATCH_DIR:-_output} # for writing files to bundle into secrets
+
+ echo Generating keystore and certificate for node ${NODE_NAME}
+
+ keytool -genkey \
+ -alias $NODE_NAME \
+ -keystore $dir/$NODE_NAME.jks \
+ -keyalg RSA \
+ -keysize 2048 \
+ -validity 712 \
+ -keypass $ks_pass \
+ -storepass $ks_pass \
+ -dname "CN=$NODE_NAME, OU=OpenShift, O=Logging"
+
+ echo Generating certificate signing request for node $NODE_NAME
+
+ keytool -certreq \
+ -alias $NODE_NAME \
+ -keystore $dir/$NODE_NAME.jks \
+ -file $dir/$NODE_NAME.jks.csr \
+ -keyalg rsa \
+ -keypass $ks_pass \
+ -storepass $ks_pass \
+ -dname "CN=$NODE_NAME, OU=OpenShift, O=Logging"
+
+ echo Sign certificate request with CA
+ openssl ca \
+ -in "$dir/$NODE_NAME.jks.csr" \
+ -notext \
+ -out "$dir/$NODE_NAME.jks.crt" \
+ -config $dir/signing.conf \
+ -extensions v3_req \
+ -batch \
+ -extensions server_ext
+
+ echo "Import back to keystore (including CA chain)"
+
+ keytool \
+ -import \
+ -file $dir/ca.crt \
+ -keystore $dir/$NODE_NAME.jks \
+ -storepass $ks_pass \
+ -noprompt -alias sig-ca
+
+ keytool \
+ -import \
+ -file $dir/$NODE_NAME.jks.crt \
+ -keystore $dir/$NODE_NAME.jks \
+ -storepass $ks_pass \
+ -noprompt \
+ -alias $NODE_NAME
+
+ echo All done for $NODE_NAME
+}
+
+function join { local IFS="$1"; shift; echo "$*"; }
+
+function createTruststore() {
+
+ echo "Import CA to truststore for validating client certs"
+
+ keytool \
+ -import \
+ -file $dir/ca.crt \
+ -keystore $dir/truststore.jks \
+ -storepass $ts_pass \
+ -noprompt -alias sig-ca
+}
+
+if [ $# -lt 1 ]; then
+ usage
+ exit 1
+fi
+
+dir=$1
+SCRATCH_DIR=$dir
+PROJECT=${2:-logging}
+
+if [[ ! -f $dir/system.admin.jks || -z "$(keytool -list -keystore $dir/system.admin.jks -storepass kspass | grep sig-ca)" ]]; then
+ generate_JKS_client_cert "system.admin"
+fi
+
+if [[ ! -f $dir/elasticsearch.jks || -z "$(keytool -list -keystore $dir/elasticsearch.jks -storepass kspass | grep sig-ca)" ]]; then
+ generate_JKS_chain true elasticsearch "$(join , logging-es{,-ops})"
+fi
+
+if [[ ! -f $dir/logging-es.jks || -z "$(keytool -list -keystore $dir/logging-es.jks -storepass kspass | grep sig-ca)" ]]; then
+ generate_JKS_chain false logging-es "$(join , logging-es{,-ops}{,-cluster}{,.${PROJECT}.svc.cluster.local})"
+fi
+
+[ ! -f $dir/truststore.jks ] && createTruststore
+
+# necessary so that the job knows it completed successfully
+exit 0
diff --git a/roles/openshift_logging/files/server-tls.json b/roles/openshift_logging/files/server-tls.json
new file mode 100644
index 000000000..86deb23e3
--- /dev/null
+++ b/roles/openshift_logging/files/server-tls.json
@@ -0,0 +1,5 @@
+// See for available options: https://nodejs.org/api/tls.html#tls_tls_createserver_options_secureconnectionlistener
+tls_options = {
+ ciphers: 'kEECDH:+kEECDH+SHA:kEDH:+kEDH+SHA:+kEDH+CAMELLIA:kECDH:+kECDH+SHA:kRSA:+kRSA+SHA:+kRSA+CAMELLIA:!aNULL:!eNULL:!SSLv2:!RC4:!DES:!EXP:!SEED:!IDEA:+3DES',
+ honorCipherOrder: true
+}
diff --git a/roles/openshift_logging/filter_plugins/openshift_logging.py b/roles/openshift_logging/filter_plugins/openshift_logging.py
new file mode 100644
index 000000000..330e7e59a
--- /dev/null
+++ b/roles/openshift_logging/filter_plugins/openshift_logging.py
@@ -0,0 +1,77 @@
+'''
+ Openshift Logging class that provides useful filters used in Logging
+'''
+
+import random
+
+
+def es_storage(os_logging_facts, dc_name, pvc_claim, root='elasticsearch'):
+ '''Return a hash with the desired storage for the given ES instance'''
+ deploy_config = os_logging_facts[root]['deploymentconfigs'].get(dc_name)
+ if deploy_config:
+ storage = deploy_config['volumes']['elasticsearch-storage']
+ if storage.get('hostPath'):
+ return dict(kind='hostpath', path=storage.get('hostPath').get('path'))
+ if len(pvc_claim.strip()) > 0:
+ return dict(kind='pvc', pvc_claim=pvc_claim)
+ return dict(kind='emptydir')
+
+
+def random_word(source_alpha, length):
+ ''' Returns a random word given the source of characters to pick from and resulting length '''
+ return ''.join(random.choice(source_alpha) for i in range(length))
+
+
+def entry_from_named_pair(register_pairs, key):
+ ''' Returns the entry in key given results provided by register_pairs '''
+ results = register_pairs.get("results")
+ if results is None:
+ raise RuntimeError("The dict argument does not have a 'results' entry. "
+ "Must not have been created using 'register' in a loop")
+ for result in results:
+ item = result.get("item")
+ if item is not None:
+ name = item.get("name")
+ if name == key:
+ return result["content"]
+ raise RuntimeError("There was no entry found in the dict that had an item with a name that matched {}".format(key))
+
+
+def map_from_pairs(source, delim="="):
+ ''' Returns a dict given the source and delim delimited '''
+ if source == '':
+ return dict()
+
+ return dict(item.split(delim) for item in source.split(","))
+
+
+def serviceaccount_name(qualified_sa):
+ ''' Returns the simple name from a fully qualified name '''
+ return qualified_sa.split(":")[-1]
+
+
+def serviceaccount_namespace(qualified_sa, default=None):
+ ''' Returns the namespace from a fully qualified name '''
+ seg = qualified_sa.split(":")
+ if len(seg) > 1:
+ return seg[-2]
+ if default:
+ return default
+ return seg[-1]
+
+
+# pylint: disable=too-few-public-methods
+class FilterModule(object):
+ ''' OpenShift Logging Filters '''
+
+ # pylint: disable=no-self-use, too-few-public-methods
+ def filters(self):
+ ''' Returns the names of the filters provided by this class '''
+ return {
+ 'random_word': random_word,
+ 'entry_from_named_pair': entry_from_named_pair,
+ 'map_from_pairs': map_from_pairs,
+ 'es_storage': es_storage,
+ 'serviceaccount_name': serviceaccount_name,
+ 'serviceaccount_namespace': serviceaccount_namespace
+ }
diff --git a/roles/openshift_logging/handlers/main.yml b/roles/openshift_logging/handlers/main.yml
new file mode 100644
index 000000000..ce7688581
--- /dev/null
+++ b/roles/openshift_logging/handlers/main.yml
@@ -0,0 +1,30 @@
+---
+- name: restart master api
+ systemd: name={{ openshift.common.service_type }}-master-api state=restarted
+ when: (not (master_api_service_status_changed | default(false) | bool)) and openshift.master.cluster_method == 'native'
+ notify: Verify API Server
+
+- name: restart master controllers
+ systemd: name={{ openshift.common.service_type }}-master-controllers state=restarted
+ when: (not (master_controllers_service_status_changed | default(false) | bool)) and openshift.master.cluster_method == 'native'
+
+- name: Verify API Server
+ # Using curl here since the uri module requires python-httplib2 and
+ # wait_for port doesn't provide health information.
+ command: >
+ curl --silent --tlsv1.2
+ {% if openshift.common.version_gte_3_2_or_1_2 | bool %}
+ --cacert {{ openshift.common.config_base }}/master/ca-bundle.crt
+ {% else %}
+ --cacert {{ openshift.common.config_base }}/master/ca.crt
+ {% endif %}
+ {{ openshift.master.api_url }}/healthz/ready
+ args:
+ # Disables the following warning:
+ # Consider using get_url or uri module rather than running curl
+ warn: no
+ register: api_available_output
+ until: api_available_output.stdout == 'ok'
+ retries: 120
+ delay: 1
+ changed_when: false
diff --git a/roles/openshift_logging/library/openshift_logging_facts.py b/roles/openshift_logging/library/openshift_logging_facts.py
new file mode 100644
index 000000000..f10df8da5
--- /dev/null
+++ b/roles/openshift_logging/library/openshift_logging_facts.py
@@ -0,0 +1,343 @@
+'''
+---
+module: openshift_logging_facts
+version_added: ""
+short_description: Gather facts about the OpenShift logging stack
+description:
+ - Determine the current facts about the OpenShift logging stack (e.g. cluster size)
+options:
+author: Red Hat, Inc
+'''
+
+import copy
+import json
+
+# pylint: disable=redefined-builtin, unused-wildcard-import, wildcard-import
+from subprocess import * # noqa: F402,F403
+
+# ignore pylint errors related to the module_utils import
+# pylint: disable=redefined-builtin, unused-wildcard-import, wildcard-import
+from ansible.module_utils.basic import * # noqa: F402,F403
+
+import yaml
+
+EXAMPLES = """
+- action: opneshift_logging_facts
+"""
+
+RETURN = """
+"""
+
+DEFAULT_OC_OPTIONS = ["-o", "json"]
+
+# constants used for various labels and selectors
+COMPONENT_KEY = "component"
+LOGGING_INFRA_KEY = "logging-infra"
+
+# selectors for filtering resources
+DS_FLUENTD_SELECTOR = LOGGING_INFRA_KEY + "=" + "fluentd"
+LOGGING_SELECTOR = LOGGING_INFRA_KEY + "=" + "support"
+ROUTE_SELECTOR = "component=support,logging-infra=support,provider=openshift"
+COMPONENTS = ["kibana", "curator", "elasticsearch", "fluentd", "kibana_ops", "curator_ops", "elasticsearch_ops"]
+
+
+class OCBaseCommand(object):
+ ''' The base class used to query openshift '''
+
+ def __init__(self, binary, kubeconfig, namespace):
+ ''' the init method of OCBaseCommand class '''
+ self.binary = binary
+ self.kubeconfig = kubeconfig
+ self.user = self.get_system_admin(self.kubeconfig)
+ self.namespace = namespace
+
+ # pylint: disable=no-self-use
+ def get_system_admin(self, kubeconfig):
+ ''' Retrieves the system admin '''
+ with open(kubeconfig, 'r') as kubeconfig_file:
+ config = yaml.load(kubeconfig_file)
+ for user in config["users"]:
+ if user["name"].startswith("system:admin"):
+ return user["name"]
+ raise Exception("Unable to find system:admin in: " + kubeconfig)
+
+ # pylint: disable=too-many-arguments, dangerous-default-value
+ def oc_command(self, sub, kind, namespace=None, name=None, add_options=None):
+ ''' Wrapper method for the "oc" command '''
+ cmd = [self.binary, sub, kind]
+ if name is not None:
+ cmd = cmd + [name]
+ if namespace is not None:
+ cmd = cmd + ["-n", namespace]
+ if add_options is None:
+ add_options = []
+ cmd = cmd + ["--user=" + self.user, "--config=" + self.kubeconfig] + DEFAULT_OC_OPTIONS + add_options
+ try:
+ process = Popen(cmd, stdout=PIPE, stderr=PIPE) # noqa: F405
+ out, err = process.communicate(cmd)
+ if len(err) > 0:
+ if 'not found' in err:
+ return {'items': []}
+ if 'No resources found' in err:
+ return {'items': []}
+ raise Exception(err)
+ except Exception as excp:
+ err = "There was an exception trying to run the command '" + " ".join(cmd) + "' " + str(excp)
+ raise Exception(err)
+
+ return json.loads(out)
+
+
+class OpenshiftLoggingFacts(OCBaseCommand):
+ ''' The class structure for holding the OpenshiftLogging Facts'''
+ name = "facts"
+
+ def __init__(self, logger, binary, kubeconfig, namespace):
+ ''' The init method for OpenshiftLoggingFacts '''
+ super(OpenshiftLoggingFacts, self).__init__(binary, kubeconfig, namespace)
+ self.logger = logger
+ self.facts = dict()
+
+ def default_keys_for(self, kind):
+ ''' Sets the default key values for kind '''
+ for comp in COMPONENTS:
+ self.add_facts_for(comp, kind)
+
+ def add_facts_for(self, comp, kind, name=None, facts=None):
+ ''' Add facts for the provided kind '''
+ if comp not in self.facts:
+ self.facts[comp] = dict()
+ if kind not in self.facts[comp]:
+ self.facts[comp][kind] = dict()
+ if name:
+ self.facts[comp][kind][name] = facts
+
+ def facts_for_routes(self, namespace):
+ ''' Gathers facts for Routes in logging namespace '''
+ self.default_keys_for("routes")
+ route_list = self.oc_command("get", "routes", namespace=namespace, add_options=["-l", ROUTE_SELECTOR])
+ if len(route_list["items"]) == 0:
+ return None
+ for route in route_list["items"]:
+ name = route["metadata"]["name"]
+ comp = self.comp(name)
+ if comp is not None:
+ self.add_facts_for(comp, "routes", name, dict(host=route["spec"]["host"]))
+ self.facts["agl_namespace"] = namespace
+
+ def facts_for_daemonsets(self, namespace):
+ ''' Gathers facts for Daemonsets in logging namespace '''
+ self.default_keys_for("daemonsets")
+ ds_list = self.oc_command("get", "daemonsets", namespace=namespace,
+ add_options=["-l", LOGGING_INFRA_KEY + "=fluentd"])
+ if len(ds_list["items"]) == 0:
+ return
+ for ds_item in ds_list["items"]:
+ name = ds_item["metadata"]["name"]
+ comp = self.comp(name)
+ spec = ds_item["spec"]["template"]["spec"]
+ container = spec["containers"][0]
+ result = dict(
+ selector=ds_item["spec"]["selector"],
+ image=container["image"],
+ resources=container["resources"],
+ nodeSelector=spec["nodeSelector"],
+ serviceAccount=spec["serviceAccount"],
+ terminationGracePeriodSeconds=spec["terminationGracePeriodSeconds"]
+ )
+ self.add_facts_for(comp, "daemonsets", name, result)
+
+ def facts_for_pvcs(self, namespace):
+ ''' Gathers facts for PVCS in logging namespace'''
+ self.default_keys_for("pvcs")
+ pvclist = self.oc_command("get", "pvc", namespace=namespace, add_options=["-l", LOGGING_INFRA_KEY])
+ if len(pvclist["items"]) == 0:
+ return
+ for pvc in pvclist["items"]:
+ name = pvc["metadata"]["name"]
+ comp = self.comp(name)
+ self.add_facts_for(comp, "pvcs", name, dict())
+
+ def facts_for_deploymentconfigs(self, namespace):
+ ''' Gathers facts for DeploymentConfigs in logging namespace '''
+ self.default_keys_for("deploymentconfigs")
+ dclist = self.oc_command("get", "deploymentconfigs", namespace=namespace, add_options=["-l", LOGGING_INFRA_KEY])
+ if len(dclist["items"]) == 0:
+ return
+ dcs = dclist["items"]
+ for dc_item in dcs:
+ name = dc_item["metadata"]["name"]
+ comp = self.comp(name)
+ if comp is not None:
+ spec = dc_item["spec"]["template"]["spec"]
+ facts = dict(
+ name=name,
+ selector=dc_item["spec"]["selector"],
+ replicas=dc_item["spec"]["replicas"],
+ serviceAccount=spec["serviceAccount"],
+ containers=dict(),
+ volumes=dict()
+ )
+ if "nodeSelector" in spec:
+ facts["nodeSelector"] = spec["nodeSelector"]
+ if "supplementalGroups" in spec["securityContext"]:
+ facts["storageGroups"] = spec["securityContext"]["supplementalGroups"]
+ facts["spec"] = spec
+ if "volumes" in spec:
+ for vol in spec["volumes"]:
+ clone = copy.deepcopy(vol)
+ clone.pop("name", None)
+ facts["volumes"][vol["name"]] = clone
+ for container in spec["containers"]:
+ facts["containers"][container["name"]] = container
+ self.add_facts_for(comp, "deploymentconfigs", name, facts)
+
+ def facts_for_services(self, namespace):
+ ''' Gathers facts for services in logging namespace '''
+ self.default_keys_for("services")
+ servicelist = self.oc_command("get", "services", namespace=namespace, add_options=["-l", LOGGING_SELECTOR])
+ if len(servicelist["items"]) == 0:
+ return
+ for service in servicelist["items"]:
+ name = service["metadata"]["name"]
+ comp = self.comp(name)
+ if comp is not None:
+ self.add_facts_for(comp, "services", name, dict())
+
+ def facts_for_configmaps(self, namespace):
+ ''' Gathers facts for configmaps in logging namespace '''
+ self.default_keys_for("configmaps")
+ a_list = self.oc_command("get", "configmaps", namespace=namespace, add_options=["-l", LOGGING_SELECTOR])
+ if len(a_list["items"]) == 0:
+ return
+ for item in a_list["items"]:
+ name = item["metadata"]["name"]
+ comp = self.comp(name)
+ if comp is not None:
+ self.add_facts_for(comp, "configmaps", name, item["data"])
+
+ def facts_for_oauthclients(self, namespace):
+ ''' Gathers facts for oauthclients used with logging '''
+ self.default_keys_for("oauthclients")
+ a_list = self.oc_command("get", "oauthclients", namespace=namespace, add_options=["-l", LOGGING_SELECTOR])
+ if len(a_list["items"]) == 0:
+ return
+ for item in a_list["items"]:
+ name = item["metadata"]["name"]
+ comp = self.comp(name)
+ if comp is not None:
+ result = dict(
+ redirectURIs=item["redirectURIs"]
+ )
+ self.add_facts_for(comp, "oauthclients", name, result)
+
+ def facts_for_secrets(self, namespace):
+ ''' Gathers facts for secrets in the logging namespace '''
+ self.default_keys_for("secrets")
+ a_list = self.oc_command("get", "secrets", namespace=namespace)
+ if len(a_list["items"]) == 0:
+ return
+ for item in a_list["items"]:
+ name = item["metadata"]["name"]
+ comp = self.comp(name)
+ if comp is not None and item["type"] == "Opaque":
+ result = dict(
+ keys=item["data"].keys()
+ )
+ self.add_facts_for(comp, "secrets", name, result)
+
+ def facts_for_sccs(self):
+ ''' Gathers facts for SCCs used with logging '''
+ self.default_keys_for("sccs")
+ scc = self.oc_command("get", "scc", name="privileged")
+ if len(scc["users"]) == 0:
+ return
+ for item in scc["users"]:
+ comp = self.comp(item)
+ if comp is not None:
+ self.add_facts_for(comp, "sccs", "privileged", dict())
+
+ def facts_for_clusterrolebindings(self, namespace):
+ ''' Gathers ClusterRoleBindings used with logging '''
+ self.default_keys_for("clusterrolebindings")
+ role = self.oc_command("get", "clusterrolebindings", name="cluster-readers")
+ if "subjects" not in role or len(role["subjects"]) == 0:
+ return
+ for item in role["subjects"]:
+ comp = self.comp(item["name"])
+ if comp is not None and namespace == item["namespace"]:
+ self.add_facts_for(comp, "clusterrolebindings", "cluster-readers", dict())
+
+# this needs to end up nested under the service account...
+ def facts_for_rolebindings(self, namespace):
+ ''' Gathers facts for RoleBindings used with logging '''
+ self.default_keys_for("rolebindings")
+ role = self.oc_command("get", "rolebindings", namespace=namespace, name="logging-elasticsearch-view-role")
+ if "subjects" not in role or len(role["subjects"]) == 0:
+ return
+ for item in role["subjects"]:
+ comp = self.comp(item["name"])
+ if comp is not None and namespace == item["namespace"]:
+ self.add_facts_for(comp, "rolebindings", "logging-elasticsearch-view-role", dict())
+
+ # pylint: disable=no-self-use, too-many-return-statements
+ def comp(self, name):
+ ''' Does a comparison to evaluate the logging component '''
+ if name.startswith("logging-curator-ops"):
+ return "curator_ops"
+ elif name.startswith("logging-kibana-ops") or name.startswith("kibana-ops"):
+ return "kibana_ops"
+ elif name.startswith("logging-es-ops") or name.startswith("logging-elasticsearch-ops"):
+ return "elasticsearch_ops"
+ elif name.startswith("logging-curator"):
+ return "curator"
+ elif name.startswith("logging-kibana") or name.startswith("kibana"):
+ return "kibana"
+ elif name.startswith("logging-es") or name.startswith("logging-elasticsearch"):
+ return "elasticsearch"
+ elif name.startswith("logging-fluentd") or name.endswith("aggregated-logging-fluentd"):
+ return "fluentd"
+ else:
+ return None
+
+ def build_facts(self):
+ ''' Builds the logging facts and returns them '''
+ self.facts_for_routes(self.namespace)
+ self.facts_for_daemonsets(self.namespace)
+ self.facts_for_deploymentconfigs(self.namespace)
+ self.facts_for_services(self.namespace)
+ self.facts_for_configmaps(self.namespace)
+ self.facts_for_sccs()
+ self.facts_for_oauthclients(self.namespace)
+ self.facts_for_clusterrolebindings(self.namespace)
+ self.facts_for_rolebindings(self.namespace)
+ self.facts_for_secrets(self.namespace)
+ self.facts_for_pvcs(self.namespace)
+
+ return self.facts
+
+
+def main():
+ ''' The main method '''
+ module = AnsibleModule( # noqa: F405
+ argument_spec=dict(
+ admin_kubeconfig={"default": "/etc/origin/master/admin.kubeconfig", "type": "str"},
+ oc_bin={"required": True, "type": "str"},
+ openshift_logging_namespace={"required": True, "type": "str"}
+ ),
+ supports_check_mode=False
+ )
+ try:
+ cmd = OpenshiftLoggingFacts(module, module.params['oc_bin'], module.params['admin_kubeconfig'],
+ module.params['openshift_logging_namespace'])
+ module.exit_json(
+ ansible_facts={"openshift_logging_facts": cmd.build_facts()}
+ )
+ # ignore broad-except error to avoid stack trace to ansible user
+ # pylint: disable=broad-except
+ except Exception as error:
+ module.fail_json(msg=str(error))
+
+
+if __name__ == '__main__':
+ main()
diff --git a/roles/openshift_logging/meta/main.yaml b/roles/openshift_logging/meta/main.yaml
new file mode 100644
index 000000000..9c480f73a
--- /dev/null
+++ b/roles/openshift_logging/meta/main.yaml
@@ -0,0 +1,16 @@
+---
+galaxy_info:
+ author: OpenShift Red Hat
+ description: OpenShift Aggregated Logging
+ company: Red Hat, Inc.
+ license: Apache License, Version 2.0
+ min_ansible_version: 2.2
+ platforms:
+ - name: EL
+ versions:
+ - 7
+ categories:
+ - cloud
+dependencies:
+- role: lib_openshift
+- role: openshift_facts
diff --git a/roles/openshift_logging/tasks/annotate_ops_projects.yaml b/roles/openshift_logging/tasks/annotate_ops_projects.yaml
new file mode 100644
index 000000000..fcb4c94d3
--- /dev/null
+++ b/roles/openshift_logging/tasks/annotate_ops_projects.yaml
@@ -0,0 +1,17 @@
+---
+- oc_obj:
+ state: list
+ kind: project
+ name: "{{ item }}"
+ with_items: "{{ __default_logging_ops_projects }}"
+ register: __logging_ops_projects
+
+- name: Annotate Operations Projects
+ oc_edit:
+ kind: ns
+ name: "{{ item.item }}"
+ separator: '#'
+ content:
+ metadata#annotations#openshift.io/logging.ui.hostname: "{{ openshift_logging_kibana_ops_hostname }}"
+ with_items: "{{ __logging_ops_projects.results }}"
+ when: item.results.stderr is not defined
diff --git a/roles/openshift_logging/tasks/delete_logging.yaml b/roles/openshift_logging/tasks/delete_logging.yaml
new file mode 100644
index 000000000..ffed956a4
--- /dev/null
+++ b/roles/openshift_logging/tasks/delete_logging.yaml
@@ -0,0 +1,114 @@
+---
+# delete the deployment objects that we had created
+- name: delete logging api objects
+ oc_obj:
+ state: absent
+ kind: "{{ item }}"
+ namespace: "{{ openshift_logging_namespace }}"
+ selector: "logging-infra"
+ with_items:
+ - dc
+ - rc
+ - svc
+ - routes
+ - templates
+ - ds
+
+# return all persistent volume claims as well if purge is set
+- name: delete logging pvc objects
+ oc_obj:
+ state: absent
+ kind: pvc
+ namespace: "{{ openshift_logging_namespace }}"
+ selector: "logging-infra"
+ when:
+ - openshift_logging_purge_logging | default(false) | bool
+
+# delete the oauthclient
+- name: delete oauthclient kibana-proxy
+ oc_obj:
+ state: absent
+ kind: oauthclient
+ namespace: "{{ openshift_logging_namespace }}"
+ name: kibana-proxy
+
+# delete any image streams that we may have created
+- name: delete logging is
+ oc_obj:
+ state: absent
+ kind: is
+ namespace: "{{ openshift_logging_namespace }}"
+ selector: "logging-infra=support"
+
+# delete our old secrets
+- name: delete logging secrets
+ oc_secret:
+ state: absent
+ namespace: "{{ openshift_logging_namespace }}"
+ name: "{{ item }}"
+ with_items:
+ - logging-fluentd
+ - logging-elasticsearch
+ - logging-kibana
+ - logging-kibana-proxy
+ - logging-curator
+ - logging-mux
+
+# delete our service accounts
+- name: delete service accounts
+ oc_serviceaccount:
+ state: absent
+ namespace: "{{ openshift_logging_namespace }}"
+ name: "{{ item }}"
+ with_items:
+ - aggregated-logging-elasticsearch
+ - aggregated-logging-kibana
+ - aggregated-logging-curator
+ - aggregated-logging-fluentd
+
+# delete role bindings
+- name: delete rolebindings
+ oc_obj:
+ state: absent
+ kind: rolebinding
+ namespace: "{{ openshift_logging_namespace }}"
+ name: logging-elasticsearch-view-role
+
+# delete cluster role bindings
+- name: delete cluster role bindings
+ oc_obj:
+ state: absent
+ kind: clusterrolebindings
+ namespace: "{{ openshift_logging_namespace }}"
+ name: rolebinding-reader
+
+# delete cluster roles
+- name: delete cluster roles
+ oc_obj:
+ state: absent
+ kind: clusterrole
+ namespace: "{{ openshift_logging_namespace }}"
+ name: "{{ item }}"
+ with_items:
+ - rolebinding-reader
+ - daemonset-admin
+ - prometheus-metrics-viewer
+
+# delete our configmaps
+- name: delete configmaps
+ oc_obj:
+ state: absent
+ kind: configmap
+ namespace: "{{ openshift_logging_namespace }}"
+ name: "{{ item }}"
+ with_items:
+ - logging-curator
+ - logging-elasticsearch
+ - logging-fluentd
+ - logging-mux
+
+## EventRouter
+- include_role:
+ name: openshift_logging_eventrouter
+ when:
+ not openshift_logging_install_eventrouter | default(false) | bool
diff --git a/roles/openshift_logging/tasks/generate_certs.yaml b/roles/openshift_logging/tasks/generate_certs.yaml
new file mode 100644
index 000000000..f526fd734
--- /dev/null
+++ b/roles/openshift_logging/tasks/generate_certs.yaml
@@ -0,0 +1,148 @@
+---
+# we will ensure our secrets and configmaps are set up here first
+- name: Checking for ca.key
+ stat: path="{{generated_certs_dir}}/ca.key"
+ register: ca_key_file
+ check_mode: no
+
+- name: Checking for ca.crt
+ stat: path="{{generated_certs_dir}}/ca.crt"
+ register: ca_cert_file
+ check_mode: no
+
+- name: Checking for ca.serial.txt
+ stat: path="{{generated_certs_dir}}/ca.serial.txt"
+ register: ca_serial_file
+ check_mode: no
+
+- name: Generate certificates
+ command: >
+ {{ openshift.common.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
+ check_mode: no
+ when:
+ - not ca_key_file.stat.exists
+ - not ca_cert_file.stat.exists
+ - not ca_serial_file.stat.exists
+
+- name: Checking for signing.conf
+ stat: path="{{generated_certs_dir}}/signing.conf"
+ register: signing_conf_file
+ check_mode: no
+
+- template: src=signing.conf.j2 dest={{generated_certs_dir}}/signing.conf
+ vars:
+ - top_dir: '{{generated_certs_dir}}'
+ when: not signing_conf_file.stat.exists
+
+- include: procure_server_certs.yaml
+ loop_control:
+ loop_var: cert_info
+ with_items:
+ - procure_component: kibana
+ - procure_component: kibana-ops
+ - procure_component: kibana-internal
+ hostnames: "kibana, kibana-ops, {{openshift_logging_kibana_hostname}}, {{openshift_logging_kibana_ops_hostname}}"
+
+- include: procure_server_certs.yaml
+ loop_control:
+ loop_var: cert_info
+ with_items:
+ - procure_component: mux
+ hostnames: "logging-mux, {{openshift_logging_mux_hostname}}"
+ when: openshift_logging_use_mux | bool
+
+- include: procure_shared_key.yaml
+ loop_control:
+ loop_var: shared_key_info
+ with_items:
+ - procure_component: mux
+ when: openshift_logging_use_mux | bool
+
+- include: procure_server_certs.yaml
+ loop_control:
+ loop_var: cert_info
+ with_items:
+ - procure_component: es
+ hostnames: "es, {{openshift_logging_es_hostname}}"
+ when: openshift_logging_es_allow_external | bool
+
+- include: procure_server_certs.yaml
+ loop_control:
+ loop_var: cert_info
+ with_items:
+ - procure_component: es-ops
+ hostnames: "es-ops, {{openshift_logging_es_ops_hostname}}"
+ when:
+ - openshift_logging_es_allow_external | bool
+ - openshift_logging_use_ops | bool
+
+- name: Copy proxy TLS configuration file
+ copy: src=server-tls.json dest={{generated_certs_dir}}/server-tls.json
+ when: server_tls_json is undefined
+ check_mode: no
+
+- name: Copy proxy TLS configuration file
+ copy: content="{{server_tls_json}}" dest={{generated_certs_dir}}/server-tls.json
+ when: server_tls_json is defined
+ check_mode: no
+
+- name: Checking for ca.db
+ stat: path="{{generated_certs_dir}}/ca.db"
+ register: ca_db_file
+ check_mode: no
+
+- copy: content="" dest={{generated_certs_dir}}/ca.db
+ check_mode: no
+ when:
+ - not ca_db_file.stat.exists
+
+- name: Checking for ca.crt.srl
+ stat: path="{{generated_certs_dir}}/ca.crt.srl"
+ register: ca_cert_srl_file
+ check_mode: no
+
+- copy: content="" dest={{generated_certs_dir}}/ca.crt.srl
+ check_mode: no
+ when:
+ - not ca_cert_srl_file.stat.exists
+
+- name: Generate PEM certs
+ include: generate_pems.yaml component={{node_name}}
+ with_items:
+ - system.logging.fluentd
+ - system.logging.kibana
+ - system.logging.curator
+ - system.admin
+ loop_control:
+ loop_var: node_name
+
+- name: Generate PEM cert for mux
+ include: generate_pems.yaml component={{node_name}}
+ with_items:
+ - system.logging.mux
+ loop_control:
+ loop_var: node_name
+ when: openshift_logging_use_mux | bool
+
+- name: Generate PEM cert for Elasticsearch external route
+ include: generate_pems.yaml component={{node_name}}
+ with_items:
+ - system.logging.es
+ loop_control:
+ loop_var: node_name
+ when: openshift_logging_es_allow_external | bool
+
+- name: Creating necessary JKS certs
+ include: generate_jks.yaml
+
+# TODO: make idempotent
+- name: Generate proxy session
+ set_fact: session_secret={{ 200 | oo_random_word}}
+ check_mode: no
+
+# TODO: make idempotent
+- name: Generate oauth client secret
+ set_fact: oauth_secret={{ 64 | oo_random_word}}
+ check_mode: no
diff --git a/roles/openshift_logging/tasks/generate_jks.yaml b/roles/openshift_logging/tasks/generate_jks.yaml
new file mode 100644
index 000000000..6e3204589
--- /dev/null
+++ b/roles/openshift_logging/tasks/generate_jks.yaml
@@ -0,0 +1,88 @@
+---
+# check if pod generated files exist -- if they all do don't run the pod
+- name: Checking for elasticsearch.jks
+ stat: path="{{generated_certs_dir}}/elasticsearch.jks"
+ register: elasticsearch_jks
+ check_mode: no
+
+- name: Checking for logging-es.jks
+ stat: path="{{generated_certs_dir}}/logging-es.jks"
+ register: logging_es_jks
+ check_mode: no
+
+- name: Checking for system.admin.jks
+ stat: path="{{generated_certs_dir}}/system.admin.jks"
+ register: system_admin_jks
+ check_mode: no
+
+- name: Checking for truststore.jks
+ stat: path="{{generated_certs_dir}}/truststore.jks"
+ register: truststore_jks
+ check_mode: no
+
+- name: Create placeholder for previously created JKS certs to prevent recreating...
+ local_action: file path="{{local_tmp.stdout}}/elasticsearch.jks" state=touch mode="u=rw,g=r,o=r"
+ when: elasticsearch_jks.stat.exists
+ changed_when: False
+
+- name: Create placeholder for previously created JKS certs to prevent recreating...
+ local_action: file path="{{local_tmp.stdout}}/logging-es.jks" state=touch mode="u=rw,g=r,o=r"
+ when: logging_es_jks.stat.exists
+ changed_when: False
+
+- name: Create placeholder for previously created JKS certs to prevent recreating...
+ local_action: file path="{{local_tmp.stdout}}/system.admin.jks" state=touch mode="u=rw,g=r,o=r"
+ when: system_admin_jks.stat.exists
+ changed_when: False
+
+- name: Create placeholder for previously created JKS certs to prevent recreating...
+ local_action: file path="{{local_tmp.stdout}}/truststore.jks" state=touch mode="u=rw,g=r,o=r"
+ when: truststore_jks.stat.exists
+ changed_when: False
+
+- name: pulling down signing items from host
+ fetch:
+ src: "{{generated_certs_dir}}/{{item}}"
+ dest: "{{local_tmp.stdout}}/{{item}}"
+ flat: yes
+ with_items:
+ - ca.crt
+ - ca.key
+ - ca.serial.txt
+ - ca.crl.srl
+ - ca.db
+ when: not elasticsearch_jks.stat.exists or not logging_es_jks.stat.exists or not system_admin_jks.stat.exists or not truststore_jks.stat.exists
+
+- local_action: template src=signing.conf.j2 dest={{local_tmp.stdout}}/signing.conf
+ vars:
+ - top_dir: "{{local_tmp.stdout}}"
+ when: not elasticsearch_jks.stat.exists or not logging_es_jks.stat.exists or not system_admin_jks.stat.exists or not truststore_jks.stat.exists
+
+- name: Run JKS generation script
+ local_action: script generate-jks.sh {{local_tmp.stdout}} {{openshift_logging_namespace}}
+ check_mode: no
+ when: not elasticsearch_jks.stat.exists or not logging_es_jks.stat.exists or not system_admin_jks.stat.exists or not truststore_jks.stat.exists
+
+- name: Pushing locally generated JKS certs to remote host...
+ copy:
+ src: "{{local_tmp.stdout}}/elasticsearch.jks"
+ dest: "{{generated_certs_dir}}/elasticsearch.jks"
+ when: not elasticsearch_jks.stat.exists
+
+- name: Pushing locally generated JKS certs to remote host...
+ copy:
+ src: "{{local_tmp.stdout}}/logging-es.jks"
+ dest: "{{generated_certs_dir}}/logging-es.jks"
+ when: not logging_es_jks.stat.exists
+
+- name: Pushing locally generated JKS certs to remote host...
+ copy:
+ src: "{{local_tmp.stdout}}/system.admin.jks"
+ dest: "{{generated_certs_dir}}/system.admin.jks"
+ when: not system_admin_jks.stat.exists
+
+- name: Pushing locally generated JKS certs to remote host...
+ copy:
+ src: "{{local_tmp.stdout}}/truststore.jks"
+ dest: "{{generated_certs_dir}}/truststore.jks"
+ when: not truststore_jks.stat.exists
diff --git a/roles/openshift_logging/tasks/generate_pems.yaml b/roles/openshift_logging/tasks/generate_pems.yaml
new file mode 100644
index 000000000..e8cececfb
--- /dev/null
+++ b/roles/openshift_logging/tasks/generate_pems.yaml
@@ -0,0 +1,37 @@
+---
+- name: Checking for {{component}}.key
+ stat: path="{{generated_certs_dir}}/{{component}}.key"
+ register: key_file
+ check_mode: no
+
+- name: Checking for {{component}}.crt
+ stat: path="{{generated_certs_dir}}/{{component}}.crt"
+ register: cert_file
+ check_mode: no
+
+- name: Creating cert req for {{component}}
+ command: >
+ openssl req -out {{generated_certs_dir}}/{{component}}.csr -new -newkey rsa:2048 -keyout {{generated_certs_dir}}/{{component}}.key
+ -subj "/CN={{component}}/OU=OpenShift/O=Logging/subjectAltName=DNS.1=localhost{{cert_ext.stdout}}" -days 712 -nodes
+ when:
+ - not key_file.stat.exists
+ - cert_ext is defined
+ - cert_ext.stdout is defined
+ check_mode: no
+
+- name: Creating cert req for {{component}}
+ command: >
+ openssl req -out {{generated_certs_dir}}/{{component}}.csr -new -newkey rsa:2048 -keyout {{generated_certs_dir}}/{{component}}.key
+ -subj "/CN={{component}}/OU=OpenShift/O=Logging" -days 712 -nodes
+ when:
+ - not key_file.stat.exists
+ - cert_ext is undefined or cert_ext is defined and cert_ext.stdout is undefined
+ check_mode: no
+
+- name: Sign cert request with CA for {{component}}
+ command: >
+ openssl ca -in {{generated_certs_dir}}/{{component}}.csr -notext -out {{generated_certs_dir}}/{{component}}.crt
+ -config {{generated_certs_dir}}/signing.conf -extensions v3_req -batch -extensions server_ext
+ when:
+ - not cert_file.stat.exists
+ check_mode: no
diff --git a/roles/openshift_logging/tasks/install_logging.yaml b/roles/openshift_logging/tasks/install_logging.yaml
new file mode 100644
index 000000000..21fd79c28
--- /dev/null
+++ b/roles/openshift_logging/tasks/install_logging.yaml
@@ -0,0 +1,282 @@
+---
+- name: Gather OpenShift Logging Facts
+ openshift_logging_facts:
+ oc_bin: "{{openshift.common.client_binary}}"
+ openshift_logging_namespace: "{{openshift_logging_namespace}}"
+
+- name: Set logging project
+ oc_project:
+ state: present
+ name: "{{ openshift_logging_namespace }}"
+ node_selector: "{{ openshift_logging_nodeselector | default(null) }}"
+
+- name: Labeling logging project
+ oc_label:
+ state: present
+ kind: namespace
+ name: "{{ openshift_logging_namespace }}"
+ labels:
+ - key: "{{ item.key }}"
+ value: "{{ item.value }}"
+ with_dict: "{{ openshift_logging_labels | default({}) }}"
+ when:
+ - openshift_logging_labels is defined
+ - openshift_logging_labels is dict
+
+- name: Labeling logging project
+ oc_label:
+ state: present
+ kind: namespace
+ name: "{{ openshift_logging_namespace }}"
+ labels:
+ - key: "{{ openshift_logging_label_key }}"
+ value: "{{ openshift_logging_label_value }}"
+ when:
+ - openshift_logging_label_key is defined
+ - openshift_logging_label_key != ""
+ - openshift_logging_label_value is defined
+
+- name: Create logging cert directory
+ file:
+ path: "{{ openshift.common.config_base }}/logging"
+ state: directory
+ mode: 0755
+ changed_when: False
+ check_mode: no
+
+- include: generate_certs.yaml
+ vars:
+ generated_certs_dir: "{{openshift.common.config_base}}/logging"
+
+## Elasticsearch
+
+- set_fact: es_indices={{ es_indices | default([]) + [item | int - 1] }}
+ with_sequence: count={{ openshift_logging_facts.elasticsearch.deploymentconfigs.keys() | count }}
+ when: openshift_logging_facts.elasticsearch.deploymentconfigs.keys() | count > 0
+
+- set_fact: es_indices=[]
+ when: openshift_logging_facts.elasticsearch.deploymentconfigs.keys() | count == 0
+
+- set_fact: openshift_logging_es_pvc_prefix="logging-es"
+ when: openshift_logging_es_pvc_prefix == ""
+
+- set_fact:
+ elasticsearch_storage_type: "{{ openshift_logging_elasticsearch_storage_type | default('pvc' if ( openshift_logging_es_pvc_dynamic | bool or openshift_hosted_logging_storage_kind | default('') == 'nfs' or openshift_logging_es_pvc_size | length > 0) else 'emptydir') }}"
+
+# We don't allow scaling down of ES nodes currently
+- include_role:
+ name: openshift_logging_elasticsearch
+ vars:
+ generated_certs_dir: "{{openshift.common.config_base}}/logging"
+ openshift_logging_elasticsearch_namespace: "{{ openshift_logging_namespace }}"
+ openshift_logging_elasticsearch_deployment_name: "{{ item.0.name }}"
+ openshift_logging_elasticsearch_pvc_name: "{{ openshift_logging_es_pvc_prefix ~ '-' ~ item.2 if item.1 is none else item.1 }}"
+ openshift_logging_elasticsearch_replica_count: "{{ openshift_logging_es_cluster_size | int }}"
+
+ openshift_logging_elasticsearch_storage_type: "{{ elasticsearch_storage_type }}"
+ openshift_logging_elasticsearch_pvc_pv_selector: "{{ openshift_logging_es_pv_selector }}"
+ openshift_logging_elasticsearch_nodeselector: "{{ openshift_logging_es_nodeselector if item.0.nodeSelector | default(None) is none else item.0.nodeSelector }}"
+ openshift_logging_elasticsearch_storage_group: "{{ [openshift_logging_es_storage_group] if item.0.storageGroups | default([]) | length == 0 else item.0.storageGroups }}"
+ _es_containers: "{{item.0.containers}}"
+
+ with_together:
+ - "{{ openshift_logging_facts.elasticsearch.deploymentconfigs.values() }}"
+ - "{{ openshift_logging_facts.elasticsearch.pvcs }}"
+ - "{{ es_indices }}"
+ when:
+ - openshift_logging_facts.elasticsearch.deploymentconfigs.keys() | count > 0
+
+# Create any new DC that may be required
+- include_role:
+ name: openshift_logging_elasticsearch
+ vars:
+ generated_certs_dir: "{{openshift.common.config_base}}/logging"
+ openshift_logging_elasticsearch_namespace: "{{ openshift_logging_namespace }}"
+ openshift_logging_elasticsearch_pvc_name: "{{ openshift_logging_es_pvc_prefix }}-{{ item | int + openshift_logging_facts.elasticsearch.deploymentconfigs | count - 1 }}"
+ openshift_logging_elasticsearch_replica_count: "{{ openshift_logging_es_cluster_size | int }}"
+
+ openshift_logging_elasticsearch_storage_type: "{{ elasticsearch_storage_type }}"
+ openshift_logging_elasticsearch_pvc_pv_selector: "{{ openshift_logging_es_pv_selector }}"
+
+ with_sequence: count={{ openshift_logging_es_cluster_size | int - openshift_logging_facts.elasticsearch.deploymentconfigs.keys() | count }}
+
+- set_fact: es_ops_indices={{ es_ops_indices | default([]) + [item | int - 1] }}
+ with_sequence: count={{ openshift_logging_facts.elasticsearch_ops.deploymentconfigs.keys() | count }}
+ when:
+ - openshift_logging_use_ops | bool
+ - openshift_logging_facts.elasticsearch_ops.deploymentconfigs.keys() | count > 0
+
+- set_fact: es_ops_indices=[]
+ when: openshift_logging_facts.elasticsearch_ops.deploymentconfigs.keys() | count == 0
+
+- set_fact: openshift_logging_es_ops_pvc_prefix="logging-es-ops"
+ when: openshift_logging_es_ops_pvc_prefix == ""
+
+- set_fact:
+ elasticsearch_storage_type: "{{ openshift_logging_elasticsearch_storage_type | default('pvc' if ( openshift_logging_es_ops_pvc_dynamic | bool or openshift_hosted_logging_storage_kind | default('') == 'nfs' or openshift_logging_es_ops_pvc_size | length > 0) else 'emptydir') }}"
+ when:
+ - openshift_logging_use_ops | bool
+
+- include_role:
+ name: openshift_logging_elasticsearch
+ vars:
+ generated_certs_dir: "{{openshift.common.config_base}}/logging"
+ openshift_logging_elasticsearch_namespace: "{{ openshift_logging_namespace }}"
+ openshift_logging_elasticsearch_deployment_name: "{{ item.0.name }}"
+ openshift_logging_elasticsearch_pvc_name: "{{ openshift_logging_es_ops_pvc_prefix ~ '-' ~ item.2 if item.1 is none else item.1 }}"
+ openshift_logging_elasticsearch_ops_deployment: true
+ openshift_logging_elasticsearch_replica_count: "{{ openshift_logging_es_ops_cluster_size | int }}"
+
+ openshift_logging_elasticsearch_storage_type: "{{ elasticsearch_storage_type }}"
+ 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_memory_limit: "{{ openshift_logging_es_ops_memory_limit }}"
+ openshift_logging_elasticsearch_cpu_limit: "{{ openshift_logging_es_ops_cpu_limit }}"
+ openshift_logging_elasticsearch_nodeselector: "{{ openshift_logging_es_ops_nodeselector if item.0.nodeSelector | default(None) is none else item.0.nodeSelector }}"
+ openshift_logging_elasticsearch_storage_group: "{{ [openshift_logging_es_ops_storage_group] if item.0.storageGroups | default([]) | length == 0 else item.0.storageGroups }}"
+ openshift_logging_es_key: "{{ openshift_logging_es_ops_key }}"
+ openshift_logging_es_cert: "{{ openshift_logging_es_ops_cert }}"
+ openshift_logging_es_ca_ext: "{{ openshift_logging_es_ops_ca_ext }}"
+ openshift_logging_es_hostname: "{{ openshift_logging_es_ops_hostname }}"
+ openshift_logging_es_edge_term_policy: "{{ openshift_logging_es_ops_edge_term_policy | default('') }}"
+ openshift_logging_es_allow_external: "{{ openshift_logging_es_ops_allow_external }}"
+ _es_containers: "{{item.0.containers}}"
+
+ with_together:
+ - "{{ openshift_logging_facts.elasticsearch_ops.deploymentconfigs.values() }}"
+ - "{{ openshift_logging_facts.elasticsearch_ops.pvcs }}"
+ - "{{ es_ops_indices }}"
+ when:
+ - openshift_logging_use_ops | bool
+ - openshift_logging_facts.elasticsearch_ops.deploymentconfigs.keys() | count > 0
+
+# Create any new DC that may be required
+- include_role:
+ name: openshift_logging_elasticsearch
+ vars:
+ generated_certs_dir: "{{openshift.common.config_base}}/logging"
+ openshift_logging_elasticsearch_namespace: "{{ openshift_logging_namespace }}"
+ openshift_logging_elasticsearch_pvc_name: "{{ openshift_logging_es_ops_pvc_prefix }}-{{ item | int + openshift_logging_facts.elasticsearch_ops.deploymentconfigs | count - 1 }}"
+ openshift_logging_elasticsearch_ops_deployment: true
+ openshift_logging_elasticsearch_replica_count: "{{ openshift_logging_es_ops_cluster_size | int }}"
+
+ openshift_logging_elasticsearch_storage_type: "{{ elasticsearch_storage_type }}"
+ 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_memory_limit: "{{ openshift_logging_es_ops_memory_limit }}"
+ openshift_logging_elasticsearch_cpu_limit: "{{ openshift_logging_es_ops_cpu_limit }}"
+ openshift_logging_elasticsearch_nodeselector: "{{ openshift_logging_es_ops_nodeselector }}"
+ openshift_logging_es_key: "{{ openshift_logging_es_ops_key }}"
+ openshift_logging_es_cert: "{{ openshift_logging_es_ops_cert }}"
+ openshift_logging_es_ca_ext: "{{ openshift_logging_es_ops_ca_ext }}"
+ openshift_logging_es_hostname: "{{ openshift_logging_es_ops_hostname }}"
+ openshift_logging_es_edge_term_policy: "{{ openshift_logging_es_ops_edge_term_policy | default('') }}"
+ openshift_logging_es_allow_external: "{{ openshift_logging_es_ops_allow_external }}"
+
+ with_sequence: count={{ openshift_logging_es_ops_cluster_size | int - openshift_logging_facts.elasticsearch_ops.deploymentconfigs.keys() | count }}
+ when:
+ - openshift_logging_use_ops | bool
+
+
+## Kibana
+- include_role:
+ name: openshift_logging_kibana
+ vars:
+ generated_certs_dir: "{{openshift.common.config_base}}/logging"
+ openshift_logging_kibana_namespace: "{{ openshift_logging_namespace }}"
+ openshift_logging_kibana_master_url: "{{ openshift_logging_master_url }}"
+ openshift_logging_kibana_master_public_url: "{{ openshift_logging_master_public_url }}"
+ openshift_logging_kibana_replicas: "{{ openshift_logging_kibana_replica_count }}"
+ openshift_logging_kibana_es_host: "{{ openshift_logging_es_host }}"
+ openshift_logging_kibana_es_port: "{{ openshift_logging_es_port }}"
+ openshift_logging_kibana_image_pull_secret: "{{ openshift_logging_image_pull_secret }}"
+
+
+- include_role:
+ name: openshift_logging_kibana
+ vars:
+ generated_certs_dir: "{{openshift.common.config_base}}/logging"
+ openshift_logging_kibana_ops_deployment: true
+ openshift_logging_kibana_namespace: "{{ openshift_logging_namespace }}"
+ openshift_logging_kibana_master_url: "{{ openshift_logging_master_url }}"
+ openshift_logging_kibana_master_public_url: "{{ openshift_logging_master_public_url }}"
+ openshift_logging_kibana_image_pull_secret: "{{ openshift_logging_image_pull_secret }}"
+ openshift_logging_kibana_es_host: "{{ openshift_logging_es_ops_host }}"
+ openshift_logging_kibana_es_port: "{{ openshift_logging_es_ops_port }}"
+ openshift_logging_kibana_nodeselector: "{{ openshift_logging_kibana_ops_nodeselector }}"
+ openshift_logging_kibana_cpu_limit: "{{ openshift_logging_kibana_ops_cpu_limit }}"
+ openshift_logging_kibana_memory_limit: "{{ openshift_logging_kibana_ops_memory_limit }}"
+ openshift_logging_kibana_hostname: "{{ openshift_logging_kibana_ops_hostname }}"
+ openshift_logging_kibana_replicas: "{{ openshift_logging_kibana_ops_replica_count }}"
+ openshift_logging_kibana_proxy_debug: "{{ openshift_logging_kibana_ops_proxy_debug }}"
+ openshift_logging_kibana_proxy_cpu_limit: "{{ openshift_logging_kibana_ops_proxy_cpu_limit }}"
+ openshift_logging_kibana_proxy_memory_limit: "{{ openshift_logging_kibana_ops_proxy_memory_limit }}"
+ openshift_logging_kibana_cert: "{{ openshift_logging_kibana_ops_cert }}"
+ openshift_logging_kibana_key: "{{ openshift_logging_kibana_ops_key }}"
+ openshift_logging_kibana_ca: "{{ openshift_logging_kibana_ops_ca}}"
+ when:
+ - openshift_logging_use_ops | bool
+
+- include: annotate_ops_projects.yaml
+
+## Curator
+- include_role:
+ name: openshift_logging_curator
+ vars:
+ generated_certs_dir: "{{openshift.common.config_base}}/logging"
+ openshift_logging_curator_namespace: "{{ openshift_logging_namespace }}"
+ openshift_logging_curator_es_host: "{{ openshift_logging_es_host }}"
+ openshift_logging_curator_es_port: "{{ openshift_logging_es_port }}"
+ openshift_logging_curator_master_url: "{{ openshift_logging_master_url }}"
+ openshift_logging_curator_image_pull_secret: "{{ openshift_logging_image_pull_secret }}"
+
+- include_role:
+ name: openshift_logging_curator
+ vars:
+ generated_certs_dir: "{{openshift.common.config_base}}/logging"
+ openshift_logging_curator_ops_deployment: true
+ openshift_logging_curator_es_host: "{{ openshift_logging_es_ops_host }}"
+ openshift_logging_curator_es_port: "{{ openshift_logging_es_ops_port }}"
+ openshift_logging_curator_namespace: "{{ openshift_logging_namespace }}"
+ openshift_logging_curator_master_url: "{{ openshift_logging_master_url }}"
+ openshift_logging_curator_image_pull_secret: "{{ openshift_logging_image_pull_secret }}"
+ openshift_logging_curator_cpu_limit: "{{ openshift_logging_curator_ops_cpu_limit }}"
+ openshift_logging_curator_memory_limit: "{{ openshift_logging_curator_ops_memory_limit }}"
+ openshift_logging_curator_nodeselector: "{{ openshift_logging_curator_ops_nodeselector }}"
+ when:
+ - openshift_logging_use_ops | bool
+
+## Mux
+- include_role:
+ name: openshift_logging_mux
+ vars:
+ generated_certs_dir: "{{openshift.common.config_base}}/logging"
+ openshift_logging_mux_ops_host: "{{ ( openshift_logging_use_ops | bool ) | ternary('logging-es-ops', 'logging-es') }}"
+ openshift_logging_mux_namespace: "{{ openshift_logging_namespace }}"
+ openshift_logging_mux_master_url: "{{ openshift_logging_master_url }}"
+ openshift_logging_mux_image_pull_secret: "{{ openshift_logging_image_pull_secret }}"
+ when:
+ - openshift_logging_use_mux | bool
+
+
+## Fluentd
+- include_role:
+ name: openshift_logging_fluentd
+ vars:
+ generated_certs_dir: "{{openshift.common.config_base}}/logging"
+ openshift_logging_fluentd_ops_host: "{{ ( openshift_logging_use_ops | bool ) | ternary('logging-es-ops', 'logging-es') }}"
+ openshift_logging_fluentd_image_pull_secret: "{{ openshift_logging_image_pull_secret }}"
+ openshift_logging_fluentd_master_url: "{{ openshift_logging_master_url }}"
+ openshift_logging_fluentd_namespace: "{{ openshift_logging_namespace }}"
+
+
+## EventRouter
+- include_role:
+ name: openshift_logging_eventrouter
+ when:
+ openshift_logging_install_eventrouter | default(false) | bool
+
+
+- include: update_master_config.yaml
diff --git a/roles/openshift_logging/tasks/main.yaml b/roles/openshift_logging/tasks/main.yaml
new file mode 100644
index 000000000..15f6a23e6
--- /dev/null
+++ b/roles/openshift_logging/tasks/main.yaml
@@ -0,0 +1,44 @@
+---
+- fail:
+ msg: Only one Fluentd nodeselector key pair should be provided
+ when: openshift_logging_fluentd_nodeselector.keys() | count > 1
+
+- name: Set default image variables based on deployment_type
+ include_vars: "{{ item }}"
+ with_first_found:
+ - "{{ openshift_deployment_type | default(deployment_type) }}.yml"
+ - "default_images.yml"
+
+- name: Set logging image facts
+ set_fact:
+ openshift_logging_image_prefix: "{{ openshift_logging_image_prefix | default(__openshift_logging_image_prefix) }}"
+ openshift_logging_image_version: "{{ openshift_logging_image_version | default(__openshift_logging_image_version) }}"
+
+- name: Create temp directory for doing work in
+ command: mktemp -d /tmp/openshift-logging-ansible-XXXXXX
+ register: mktemp
+ changed_when: False
+ check_mode: no
+ tags: logging_init
+
+- debug: msg="Created temp dir {{mktemp.stdout}}"
+
+- name: Create local temp directory for doing work in
+ local_action: command mktemp -d /tmp/openshift-logging-ansible-XXXXXX
+ register: local_tmp
+ changed_when: False
+ check_mode: no
+ become: no
+
+- include: install_logging.yaml
+ when:
+ - openshift_logging_install_logging | default(false) | bool
+
+- include: delete_logging.yaml
+ when:
+ - not openshift_logging_install_logging | default(false) | bool
+
+- name: Cleaning up local temp dir
+ local_action: file path="{{local_tmp.stdout}}" state=absent
+ tags: logging_cleanup
+ changed_when: False
diff --git a/roles/openshift_logging/tasks/procure_server_certs.yaml b/roles/openshift_logging/tasks/procure_server_certs.yaml
new file mode 100644
index 000000000..00de0ca06
--- /dev/null
+++ b/roles/openshift_logging/tasks/procure_server_certs.yaml
@@ -0,0 +1,58 @@
+---
+- name: Checking for {{ cert_info.procure_component }}.crt
+ stat: path="{{generated_certs_dir}}/{{ cert_info.procure_component }}.crt"
+ register: component_cert_file
+ check_mode: no
+
+- name: Checking for {{ cert_info.procure_component }}.key
+ stat: path="{{generated_certs_dir}}/{{ cert_info.procure_component }}.key"
+ register: component_key_file
+ check_mode: no
+
+- name: Trying to discover server cert variable name for {{ cert_info.procure_component }}
+ set_fact: procure_component_crt={{ lookup('env', '{{cert_info.procure_component}}' + '_crt') }}
+ when:
+ - cert_info.hostnames is undefined
+ - cert_info[ cert_info.procure_component + '_crt' ] is defined
+ - cert_info[ cert_info.procure_component + '_key' ] is defined
+ check_mode: no
+
+- name: Trying to discover the server key variable name for {{ cert_info.procure_component }}
+ set_fact: procure_component_key={{ lookup('env', '{{cert_info.procure_component}}' + '_key') }}
+ when:
+ - cert_info.hostnames is undefined
+ - cert_info[ cert_info.procure_component + '_crt' ] is defined
+ - cert_info[ cert_info.procure_component + '_key' ] is defined
+ check_mode: no
+
+- name: Creating signed server cert and key for {{ cert_info.procure_component }}
+ command: >
+ {{ openshift.common.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
+ check_mode: no
+ when:
+ - cert_info.hostnames is defined
+ - not component_key_file.stat.exists
+ - not component_cert_file.stat.exists
+
+- name: Copying server key for {{ cert_info.procure_component }} to generated certs directory
+ copy: content="{{procure_component_key}}" dest={{generated_certs_dir}}/{{cert_info.procure_component}}.key
+ check_mode: no
+ when:
+ - cert_info.hostnames is undefined
+ - cert_info[ cert_info.procure_component + '_crt' ] is defined
+ - cert_info[ cert_info.procure_component + '_key' ] is defined
+ - not component_key_file.stat.exists
+ - not component_cert_file.stat.exists
+
+- name: Copying Server cert for {{ cert_info.procure_component }} to generated certs directory
+ copy: content="{{procure_component_crt}}" dest={{generated_certs_dir}}/{{cert_info.procure_component}}.crt
+ check_mode: no
+ when:
+ - cert_info.hostnames is undefined
+ - cert_info[ cert_info.procure_component + '_crt' ] is defined
+ - cert_info[ cert_info.procure_component + '_key' ] is defined
+ - not component_key_file.stat.exists
+ - not component_cert_file.stat.exists
diff --git a/roles/openshift_logging/tasks/procure_shared_key.yaml b/roles/openshift_logging/tasks/procure_shared_key.yaml
new file mode 100644
index 000000000..056ff6b98
--- /dev/null
+++ b/roles/openshift_logging/tasks/procure_shared_key.yaml
@@ -0,0 +1,25 @@
+---
+- name: Checking for {{ shared_key_info.procure_component }}_shared_key
+ stat: path="{{generated_certs_dir}}/{{ shared_key_info.procure_component }}_shared_key"
+ register: component_shared_key_file
+ check_mode: no
+
+- name: Trying to discover shared key variable name for {{ shared_key_info.procure_component }}
+ set_fact: procure_component_shared_key={{ lookup('env', '{{shared_key_info.procure_component}}' + '_shared_key') }}
+ when:
+ - shared_key_info[ shared_key_info.procure_component + '_shared_key' ] is defined
+ check_mode: no
+
+- name: Creating shared_key for {{ shared_key_info.procure_component }}
+ copy: content="{{'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'|random_word(64)}}"
+ dest="{{generated_certs_dir}}/{{shared_key_info.procure_component}}_shared_key"
+ check_mode: no
+ when:
+ - not component_shared_key_file.stat.exists
+
+- name: Copying shared key for {{ shared_key_info.procure_component }} to generated certs directory
+ copy: content="{{procure_component_shared_key}}" dest="{{generated_certs_dir}}/{{shared_key_info.procure_component}}_shared_key"
+ check_mode: no
+ when:
+ - shared_key_info[ shared_key_info.procure_component + '_shared_key' ] is defined
+ - not component_shared_key_file.stat.exists
diff --git a/roles/openshift_logging/tasks/update_master_config.yaml b/roles/openshift_logging/tasks/update_master_config.yaml
new file mode 100644
index 000000000..b96b8e29d
--- /dev/null
+++ b/roles/openshift_logging/tasks/update_master_config.yaml
@@ -0,0 +1,11 @@
+---
+- name: Adding Kibana route information to loggingPublicURL
+ modify_yaml:
+ dest: "{{ openshift.common.config_base }}/master/master-config.yaml"
+ yaml_key: assetConfig.loggingPublicURL
+ yaml_value: "https://{{ openshift_logging_kibana_hostname }}"
+ notify:
+ - restart master api
+ - restart master controllers
+ tags:
+ - update_master_config
diff --git a/roles/openshift_logging/templates/jks_pod.j2 b/roles/openshift_logging/templates/jks_pod.j2
new file mode 100644
index 000000000..8b1c74211
--- /dev/null
+++ b/roles/openshift_logging/templates/jks_pod.j2
@@ -0,0 +1,28 @@
+apiVersion: v1
+kind: Pod
+metadata:
+ labels:
+ logging-infra: support
+ generateName: jks-cert-gen-
+spec:
+ containers:
+ - name: jks-cert-gen
+ image: {{openshift_logging_image_prefix}}logging-deployer:{{openshift_logging_image_version}}
+ imagePullPolicy: Always
+ command: ["sh", "{{generated_certs_dir}}/generate-jks.sh"]
+ securityContext:
+ privileged: true
+ volumeMounts:
+ - mountPath: {{generated_certs_dir}}
+ name: certmount
+ env:
+ - name: PROJECT
+ value: {{openshift_logging_namespace}}
+ - name: CERT_DIR
+ value: {{generated_certs_dir}}
+ restartPolicy: Never
+ serviceAccount: jks-generator
+ volumes:
+ - hostPath:
+ path: "{{generated_certs_dir}}"
+ name: certmount
diff --git a/roles/openshift_logging/templates/signing.conf.j2 b/roles/openshift_logging/templates/signing.conf.j2
new file mode 100644
index 000000000..727cde4c9
--- /dev/null
+++ b/roles/openshift_logging/templates/signing.conf.j2
@@ -0,0 +1,103 @@
+# Simple Signing CA
+
+# The [default] section contains global constants that can be referred to from
+# the entire configuration file. It may also hold settings pertaining to more
+# than one openssl command.
+
+[ default ]
+dir = {{top_dir}} # Top dir
+
+# The next part of the configuration file is used by the openssl req command.
+# It defines the CA's key pair, its DN, and the desired extensions for the CA
+# certificate.
+
+[ req ]
+default_bits = 2048 # RSA key size
+encrypt_key = yes # Protect private key
+default_md = sha1 # MD to use
+utf8 = yes # Input is UTF-8
+string_mask = utf8only # Emit UTF-8 strings
+prompt = no # Don't prompt for DN
+distinguished_name = ca_dn # DN section
+req_extensions = ca_reqext # Desired extensions
+
+[ ca_dn ]
+0.domainComponent = "io"
+1.domainComponent = "openshift"
+organizationName = "OpenShift Origin"
+organizationalUnitName = "Logging Signing CA"
+commonName = "Logging Signing CA"
+
+[ ca_reqext ]
+keyUsage = critical,keyCertSign,cRLSign
+basicConstraints = critical,CA:true,pathlen:0
+subjectKeyIdentifier = hash
+
+# The remainder of the configuration file is used by the openssl ca command.
+# The CA section defines the locations of CA assets, as well as the policies
+# applying to the CA.
+
+[ ca ]
+default_ca = signing_ca # The default CA section
+
+[ signing_ca ]
+certificate = $dir/ca.crt # The CA cert
+private_key = $dir/ca.key # CA private key
+new_certs_dir = $dir/ # Certificate archive
+serial = $dir/ca.serial.txt # Serial number file
+crlnumber = $dir/ca.crl.srl # CRL number file
+database = $dir/ca.db # Index file
+unique_subject = no # Require unique subject
+default_days = 730 # How long to certify for
+default_md = sha1 # MD to use
+policy = any_pol # Default naming policy
+email_in_dn = no # Add email to cert DN
+preserve = no # Keep passed DN ordering
+name_opt = ca_default # Subject DN display options
+cert_opt = ca_default # Certificate display options
+copy_extensions = copy # Copy extensions from CSR
+x509_extensions = client_ext # Default cert extensions
+default_crl_days = 7 # How long before next CRL
+crl_extensions = crl_ext # CRL extensions
+
+# Naming policies control which parts of a DN end up in the certificate and
+# under what circumstances certification should be denied.
+
+[ match_pol ]
+domainComponent = match # Must match 'simple.org'
+organizationName = match # Must match 'Simple Inc'
+organizationalUnitName = optional # Included if present
+commonName = supplied # Must be present
+
+[ any_pol ]
+domainComponent = optional
+countryName = optional
+stateOrProvinceName = optional
+localityName = optional
+organizationName = optional
+organizationalUnitName = optional
+commonName = optional
+emailAddress = optional
+
+# Certificate extensions define what types of certificates the CA is able to
+# create.
+
+[ client_ext ]
+keyUsage = critical,digitalSignature,keyEncipherment
+basicConstraints = CA:false
+extendedKeyUsage = clientAuth
+subjectKeyIdentifier = hash
+authorityKeyIdentifier = keyid
+
+[ server_ext ]
+keyUsage = critical,digitalSignature,keyEncipherment
+basicConstraints = CA:false
+extendedKeyUsage = serverAuth,clientAuth
+subjectKeyIdentifier = hash
+authorityKeyIdentifier = keyid
+
+# CRL extensions exist solely to point to the CA certificate that has issued
+# the CRL.
+
+[ crl_ext ]
+authorityKeyIdentifier = keyid
diff --git a/roles/openshift_logging/vars/default_images.yml b/roles/openshift_logging/vars/default_images.yml
new file mode 100644
index 000000000..1a77808f6
--- /dev/null
+++ b/roles/openshift_logging/vars/default_images.yml
@@ -0,0 +1,3 @@
+---
+__openshift_logging_image_prefix: "{{ openshift_hosted_logging_deployer_prefix | default('docker.io/openshift/origin-') }}"
+__openshift_logging_image_version: "{{ openshift_hosted_logging_deployer_version | default('latest') }}"
diff --git a/roles/openshift_logging/vars/main.yaml b/roles/openshift_logging/vars/main.yaml
new file mode 100644
index 000000000..01809fddf
--- /dev/null
+++ b/roles/openshift_logging/vars/main.yaml
@@ -0,0 +1,10 @@
+---
+openshift_master_config_dir: "{{ openshift.common.config_base }}/master"
+es_node_quorum: "{{ (openshift_logging_es_cluster_size | int/2 | round(0,'floor') + 1) | int}}"
+es_recover_expected_nodes: "{{openshift_logging_es_cluster_size | int}}"
+es_ops_node_quorum: "{{ (openshift_logging_es_ops_cluster_size | int/2 | round(0,'floor') + 1) | int}}"
+es_ops_recover_expected_nodes: "{{openshift_logging_es_ops_cluster_size | int}}"
+
+es_log_appenders: ['file', 'console']
+
+__default_logging_ops_projects: ['default', 'openshift', 'openshift-infra', 'kube-system']
diff --git a/roles/openshift_logging/vars/openshift-enterprise.yml b/roles/openshift_logging/vars/openshift-enterprise.yml
new file mode 100644
index 000000000..f60fa8d7d
--- /dev/null
+++ b/roles/openshift_logging/vars/openshift-enterprise.yml
@@ -0,0 +1,3 @@
+---
+__openshift_logging_image_prefix: "{{ openshift_hosted_logging_deployer_prefix | default('registry.access.redhat.com/openshift3/') }}"
+__openshift_logging_image_version: "{{ openshift_hosted_logging_deployer_version | default ('v3.7') }}"