diff options
247 files changed, 9294 insertions, 1023 deletions
@@ -1,5 +1,5 @@ [flake8] # TODO: cleanup flake8 issues with utils/test/* -exclude=.tox,inventory,utils/test +exclude=.tox,inventory max_line_length = 120 ignore = E501,T003 diff --git a/.tito/packages/openshift-ansible b/.tito/packages/openshift-ansible index 203ed61cc..d6dd5a3c8 100644 --- a/.tito/packages/openshift-ansible +++ b/.tito/packages/openshift-ansible @@ -1 +1 @@ -3.9.0-0.16.0 ./ +3.9.0-0.23.0 ./ diff --git a/ansible.cfg b/ansible.cfg index c1c76a496..67149cb35 100644 --- a/ansible.cfg +++ b/ansible.cfg @@ -22,7 +22,7 @@ fact_caching = jsonfile fact_caching_connection = $HOME/ansible/facts fact_caching_timeout = 600 callback_whitelist = profile_tasks -inventory_ignore_extensions = secrets.py, .pyc, .cfg, .crt +inventory_ignore_extensions = secrets.py, .pyc, .cfg, .crt, .ini # work around privilege escalation timeouts in ansible: timeout = 30 diff --git a/files/origin-components/apiserver-template.yaml b/files/origin-components/apiserver-template.yaml index 035e4734b..4dd9395d0 100644 --- a/files/origin-components/apiserver-template.yaml +++ b/files/origin-components/apiserver-template.yaml @@ -4,7 +4,7 @@ metadata: name: template-service-broker-apiserver parameters: - name: IMAGE - value: openshift/origin:latest + value: openshift/origin-template-service-broker:latest - name: NAMESPACE value: openshift-template-service-broker - name: LOGLEVEL @@ -40,14 +40,14 @@ objects: image: ${IMAGE} imagePullPolicy: IfNotPresent command: - - "/usr/bin/openshift" + - "/usr/bin/template-service-broker" - "start" - "template-service-broker" - "--secure-port=8443" - "--audit-log-path=-" - "--tls-cert-file=/var/serving-cert/tls.crt" - "--tls-private-key-file=/var/serving-cert/tls.key" - - "--loglevel=${LOGLEVEL}" + - "--v=${LOGLEVEL}" - "--config=/var/apiserver-config/apiserver-config.yaml" ports: - containerPort: 8443 diff --git a/files/origin-components/console-config.yaml b/files/origin-components/console-config.yaml index 8f3f87c0b..32a28775f 100644 --- a/files/origin-components/console-config.yaml +++ b/files/origin-components/console-config.yaml @@ -1,15 +1,17 @@ -kind: AssetConfig -apiVersion: v1 -extensionDevelopment: false -extensionProperties: null -extensionScripts: null -extensionStylesheets: null -extensions: null -loggingPublicURL: "" -logoutURL: "" -masterPublicURL: https://127.0.0.1:8443 -metricsPublicURL: "" -publicURL: https://127.0.0.1:8443/console/ +apiVersion: webconsole.config.openshift.io/v1 +kind: WebConsoleConfiguration +clusterInfo: + consolePublicURL: https://127.0.0.1:8443/console/ + loggingPublicURL: "" + logoutPublicURL: "" + masterPublicURL: https://127.0.0.1:8443 + metricsPublicURL: "" +extensions: + scriptURLs: [] + stylesheetURLs: [] + properties: null +features: + inactivityTimeoutMinutes: 0 servingInfo: bindAddress: 0.0.0.0:8443 bindNetwork: tcp4 @@ -18,4 +20,4 @@ servingInfo: keyFile: /var/serving-cert/tls.key maxRequestsInFlight: 0 namedCertificates: null - requestTimeoutSeconds: 0
\ No newline at end of file + requestTimeoutSeconds: 0 diff --git a/files/origin-components/console-rbac-template.yaml b/files/origin-components/console-rbac-template.yaml new file mode 100644 index 000000000..9ee117199 --- /dev/null +++ b/files/origin-components/console-rbac-template.yaml @@ -0,0 +1,38 @@ +apiVersion: template.openshift.io/v1 +kind: Template +metadata: + name: web-console-server-rbac +parameters: +- name: NAMESPACE + # This namespace cannot be changed. Only `openshift-web-console` is supported. + value: openshift-web-console +objects: + + +# allow grant powers to the webconsole server for cluster inspection +- apiVersion: rbac.authorization.k8s.io/v1beta1 + kind: ClusterRole + metadata: + name: system:openshift:web-console-server + rules: + - apiGroups: + - "servicecatalog.k8s.io" + resources: + - clusterservicebrokers + verbs: + - get + - list + - watch + +# Grant the service account for the web console +- apiVersion: rbac.authorization.k8s.io/v1beta1 + kind: ClusterRoleBinding + metadata: + name: system:openshift:web-console-server + roleRef: + kind: ClusterRole + name: system:openshift:web-console-server + subjects: + - kind: ServiceAccount + namespace: ${NAMESPACE} + name: webconsole diff --git a/files/origin-components/console-template.yaml b/files/origin-components/console-template.yaml index b2a6569fd..7bf2d0cf4 100644 --- a/files/origin-components/console-template.yaml +++ b/files/origin-components/console-template.yaml @@ -14,6 +14,7 @@ parameters: - name: IMAGE value: openshift/origin-web-console:latest - name: NAMESPACE + # This namespace cannot be changed. Only `openshift-web-console` is supported. value: openshift-web-console - name: LOGLEVEL value: "0" @@ -51,6 +52,7 @@ objects: command: - "/usr/bin/origin-web-console" - "--audit-log-path=-" + - "-v=${LOGLEVEL}" - "--config=/var/webconsole-config/webconsole-config.yaml" ports: - containerPort: 8443 @@ -64,15 +66,20 @@ objects: path: /healthz port: 8443 scheme: HTTPS + livenessProbe: + httpGet: + path: / + port: 8443 + scheme: HTTPS nodeSelector: "${{NODE_SELECTOR}}" volumes: - name: serving-cert secret: - defaultMode: 420 + defaultMode: 400 secretName: webconsole-serving-cert - name: webconsole-config configMap: - defaultMode: 420 + defaultMode: 440 name: webconsole-config # to create the config for the web console diff --git a/images/installer/Dockerfile b/images/installer/Dockerfile index db362bd65..b1390480a 100644 --- a/images/installer/Dockerfile +++ b/images/installer/Dockerfile @@ -10,7 +10,7 @@ COPY images/installer/origin-extra-root / # install ansible and deps RUN INSTALL_PKGS="python-lxml pyOpenSSL python2-cryptography openssl java-1.8.0-openjdk-headless python2-passlib httpd-tools openssh-clients origin-clients" \ && yum install -y --setopt=tsflags=nodocs $INSTALL_PKGS \ - && EPEL_PKGS="ansible python2-boto google-cloud-sdk-183.0.0 which" \ + && EPEL_PKGS="ansible python2-boto python2-boto3 google-cloud-sdk-183.0.0 which" \ && yum install -y epel-release \ && yum install -y --setopt=tsflags=nodocs $EPEL_PKGS \ && rpm -V $INSTALL_PKGS $EPEL_PKGS \ diff --git a/inventory/hosts.example b/inventory/hosts.example index 05293269d..f9f331880 100644 --- a/inventory/hosts.example +++ b/inventory/hosts.example @@ -286,8 +286,21 @@ openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true', #openshift_cloudprovider_openstack_region=region #openshift_cloudprovider_openstack_lb_subnet_id=subnet_id # +# Note: If you're getting a "BS API version autodetection failed" when provisioning cinder volumes you may need this setting +#openshift_cloudprovider_openstack_blockstorage_version=v2 +# # GCE #openshift_cloudprovider_kind=gce +# +# vSphere +#openshift_cloudprovider_kind=vsphere +#openshift_cloudprovider_vsphere_username=username +#openshift_cloudprovider_vsphere_password=password +#openshift_cloudprovider_vsphere_host=vcenter_host or vsphere_host +#openshift_cloudprovider_vsphere_datacenter=datacenter +#openshift_cloudprovider_vsphere_datastore=datastore +#openshift_cloudprovider_vsphere_folder=optional_folder_name + # Project Configuration #osm_project_request_message='' @@ -832,12 +845,12 @@ openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true', # See: https://github.com/nickhammond/ansible-logrotate #logrotate_scripts=[{"name": "syslog", "path": "/var/log/cron\n/var/log/maillog\n/var/log/messages\n/var/log/secure\n/var/log/spooler\n", "options": ["daily", "rotate 7", "compress", "sharedscripts", "missingok"], "scripts": {"postrotate": "/bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true"}}] -# openshift-ansible will wait indefinitely for your input when it detects that the +# The OpenShift-Ansible installer will fail when it detects that the # value of openshift_hostname resolves to an IP address not bound to any local # interfaces. This mis-configuration is problematic for any pod leveraging host # networking and liveness or readiness probes. -# Setting this variable to true will override that check. -#openshift_override_hostname_check=true +# Setting this variable to false will override that check. +#openshift_hostname_check=true # openshift_use_dnsmasq is deprecated. This must be true, or installs will fail # in versions >= 3.6 @@ -899,6 +912,7 @@ openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true', #openshift_buildoverrides_image_labels=[{'name':'imagelabelname1','value':'imagelabelvalue1'}] #openshift_buildoverrides_nodeselectors={'nodelabel1':'nodelabelvalue1'} #openshift_buildoverrides_annotations={'annotationkey1':'annotationvalue1'} +#openshift_buildoverrides_tolerations=[{'key':'mykey1','value':'myvalue1','effect':'NoSchedule','operator':'Equal'}] # Or you may optionally define your own build overrides configuration serialized as json #openshift_buildoverrides_json='{"BuildOverrides":{"configuration":{"apiVersion":"v1","kind":"BuildDefaultsConfig","forcePull":"true"}}}' @@ -995,6 +1009,14 @@ openshift_master_identity_providers=[{'name': 'htpasswd_auth', 'login': 'true', # where as this would not # openshift_upgrade_nodes_serial=4 openshift_upgrade_nodes_max_fail_percentage=50 # +# A timeout to wait for nodes to drain pods can be specified to ensure that the +# upgrade continues even if nodes fail to drain pods in the allowed time. The +# default value of 0 will wait indefinitely allowing the admin to investigate +# the root cause and ensuring that disruption budgets are respected. If the +# a timeout of 0 is used there will also be one attempt to re-try draining the +# node. If a non zero timeout is specified there will be no attempt to retry. +#openshift_upgrade_nodes_drain_timeout=0 +# # Multiple data migrations take place and if they fail they will fail the upgrade # You may wish to disable these or make them non fatal # diff --git a/inventory/hosts.grafana.example b/inventory/hosts.grafana.example new file mode 100644 index 000000000..a5999578f --- /dev/null +++ b/inventory/hosts.grafana.example @@ -0,0 +1,12 @@ +[OSEv3:children] +masters +nodes + +[OSEv3:vars] +# Grafana Configuration +#gf_datasource_name="example" +#gf_prometheus_namespace="openshift-metrics" +#gf_oauth=true + +[masters] +master diff --git a/openshift-ansible.spec b/openshift-ansible.spec index 06f5d3669..c09e14c66 100644 --- a/openshift-ansible.spec +++ b/openshift-ansible.spec @@ -10,7 +10,7 @@ Name: openshift-ansible Version: 3.9.0 -Release: 0.16.0%{?dist} +Release: 0.23.0%{?dist} Summary: Openshift and Atomic Enterprise Ansible License: ASL 2.0 URL: https://github.com/openshift/openshift-ansible @@ -202,6 +202,211 @@ Atomic OpenShift Utilities includes %changelog +* Tue Jan 23 2018 Jenkins CD Merge Bot <smunilla@redhat.com> 3.9.0-0.23.0 +- docker_image_availability: enable skopeo to use proxies (lmeyer@redhat.com) +- Install base_packages earlier (mgugino@redhat.com) +- allow uninstalling AWS objects created by prerequisite playbook + (jdiaz@redhat.com) +- Bug 1536262: Default console and TSB node selector to + openshift_hosted_infra_selector (spadgett@redhat.com) +- Migrate master-config.yaml asset config (spadgett@redhat.com) +- Fix master scaleup play (mgugino@redhat.com) +- use admin credentials for tsb install operations (bparees@redhat.com) +- Fix etcd-upgrade sanity checks (mgugino@redhat.com) +- Bug 1536253: Pass `--config` flag on oc commands when installing console + (spadgett@redhat.com) +- Fix enterprise registry-console prefix (sdodson@redhat.com) +- [release-3.7] Fix enterprise registry console image prefix + (sdodson@redhat.com) +- [release-3.6] Fix enterprise registry console image prefix + (sdodson@redhat.com) +- Bug 1512825 - add mux pod failed for Serial number 02 has already been issued + (nhosoi@redhat.com) +- Remove old console asset config (spadgett@redhat.com) +- Add support for Amazon EC2 C5 instance types (rteague@redhat.com) +- Fix provider network support at openstack playbook (ltomasbo@redhat.com) + +* Fri Jan 19 2018 Jenkins CD Merge Bot <smunilla@redhat.com> 3.9.0-0.22.0 +- Fix OpenStack readme (tomas@sedovic.cz) +- Quick installer: deprecate upgrades (vrutkovs@redhat.com) +- Fix node scaleup plays (mgugino@redhat.com) +- Rollout console after template service broker install (spadgett@redhat.com) +- Use openshift_is_containerized instead of openshift_is_atomic when installing + etcd (vrutkovs@redhat.com) +- Bug 1535947: Fix missing task in metrics, logging uninstall playbooks + (spadgett@redhat.com) +- Make openshift_web_console_prefix defaults like other components + (sdodson@redhat.com) +- Allow for firewalld on atomic host (sdodson@redhat.com) +- Drop the testing repo var from openstack readme (tomas@sedovic.cz) +- Add Azure to support openshift_cloudprovider_kind (wehe@redhat.com) +- bug 1523047. Annotate ops projects with an .operation prefix + (jcantril@redhat.com) +- Pull openshift_image_tag from oo_masters_to_config rather oo_first_master. + (abutcher@redhat.com) +- Ensure atomic_proxies are configured with docker (mgugino@redhat.com) +- Default install_result when reloading generated facts. (abutcher@redhat.com) +- health checks: update required pkg versions (lmeyer@redhat.com) +- health checks: factor out get_required_version (lmeyer@redhat.com) +- package_version check: reuse get_major_minor_version (lmeyer@redhat.com) +- Rework default TSB prefix and imagename to match other services + (vrutkovs@redhat.com) +- Add new grafana playbook. (mrsiano@gmail.com) +- Remove duplication in node acceptance playbook and setup master groups so + that we can use the first master's ansible_ssh_user when delegating. + (abutcher@redhat.com) +- Setting default storage_class_names for when calling + openshift_logging_elasticsearch role (ewolinet@redhat.com) +- adding check if secret auth is needed (shawn.hurley21@gmail.com) +- adding asb auth as a secret. (shawn.hurley21@gmail.com) +- Ensure we are running oc execs against running pods (ewolinet@redhat.com) +- Automatic profile setting for tuned 2.9 (jmencak@redhat.com) +- Fix flake8 errors in utils/test (vrutkovs@redhat.com) +- kibana checks: use six.moves instead of ImportError (vrutkovs@redhat.com) + +* Wed Jan 17 2018 Jenkins CD Merge Bot <smunilla@redhat.com> 3.9.0-0.21.0 +- Add call to 3.8 playbook in 3.9 upgrade (sdodson@redhat.com) +- Remove 3.8 and 3.9 specific steps right now (sdodson@redhat.com) +- Exclude 3.9 packages during 3.8 upgrade (sdodson@redhat.com) +- fix typos (sdodson@redhat.com) +- Ensure openshift_client_binary is set (sdodson@redhat.com) +- Add init/main.yml to etc-upgrade (mgugino@redhat.com) +- Fix a typo in "Determine if growpart is installed" (vrutkovs@redhat.com) +- Check rc for commands with openshift_client_binary and failed_when + (vrutkovs@redhat.com) +- Update console config for API changes (spadgett@redhat.com) +- include elasticsearch container name (jvallejo@redhat.com) +- openshift_checks: repair adhoc list-checks mode (lmeyer@redhat.com) +- Remove tuned-profiles from list of master packages upgraded + (sdodson@redhat.com) +- Add missing task that got dropped in a refactor (sdodson@redhat.com) +- Web Console: use a different var for asset config (vrutkovs@redhat.com) +- Document the inventory change (tomas@sedovic.cz) +- Move the OpenStack dynamic inventory from sample (tomas@sedovic.cz) +- fix bug 1534271 (wmeng@redhat.com) +- Don't use from ansible.module_utils.six as its no longer available in Ansible + 2.4 (vrutkovs@redhat.com) +- Add console RBAC template (spadgett@redhat.com) +- Setup master groups in order to use the master group's ansible_ssh_user to + pull bootstrap kubeconfig. (abutcher@redhat.com) +- adding ability to add network policy objects. (shawn.hurley21@gmail.com) +- add python2-boto3 package for centos-based origin-ansible container image + (jdiaz@redhat.com) +- adding ability to interact with network resources. (shawn.hurley21@gmail.com) +- Adding .ini to inventory_ignore_extensions (bedin@redhat.com) + +* Mon Jan 15 2018 Jenkins CD Merge Bot <smunilla@redhat.com> 3.9.0-0.20.0 +- Adjust openstack provider dependencies versions (bdobreli@redhat.com) +- Fix openstack provider playbook name in docs (bdobreli@redhat.com) +- Install web console on upgrade (spadgett@redhat.com) +- Add var for controller to enable async bindings (jpeeler@redhat.com) +- Add cluster-operator playbook directory. (abutcher@redhat.com) +- Move s3 & elb provisioning into their own playbooks s.t. they are applied + outside of the openshift_aws master provisioning tasks. (abutcher@redhat.com) +- Update to AWS EC2 root vol size so that Health Check tasks pass + (mazzystr@gmail.com) +- Configure Kuryr CNI daemon (mdulko@redhat.com) +- Clean up host-local IPAM data while nodes are drained (danw@redhat.com) + +* Fri Jan 12 2018 Jenkins CD Merge Bot <smunilla@redhat.com> 3.9.0-0.19.0 +- + +* Fri Jan 12 2018 Jenkins CD Merge Bot <smunilla@redhat.com> 3.9.0-0.18.0 +- + +* Fri Jan 12 2018 Jenkins CD Merge Bot <smunilla@redhat.com> 3.9.0-0.17.0 +- Update latest image streams and templates (sdodson@redhat.com) +- Use webconsole.config.openshift.io/v1 API group (spadgett@redhat.com) +- Add missing v3.9 gluster templates (sdodson@redhat.com) +- Spelling and grammar changes to the advanced-configuration.md file. + (mbruzek@gmail.com) +- Fixing openshift_hosted variable. (kwoodson@redhat.com) +- Update deployment and apiserver with new certs (jpeeler@redhat.com) +- Move more plugins to lib_utils (mgugino@redhat.com) +- Add the ability to specify a timeout for node drain operations + (sdodson@redhat.com) +- Add defaults for openshift_pkg_version (mgugino@redhat.com) +- Fix typo in the advanced config docs (tomas@sedovic.cz) +- Write guide on setting up PVs with Cinder (tomas@sedovic.cz) +- Allow using server names in openstack dynamic inv (tomas@sedovic.cz) +- Specify the Cinder version in the inventory (tomas@sedovic.cz) +- Add documentation example (joel.pearson@gmail.com) +- Add blockstorage version for openstack (joel.pearson@gmail.com) +- logging: fix jinja filters to support py3 (vrutkovs@redhat.com) +- Ability to specify override tolerations via the buildconfig overrider + (cdaley@redhat.com) +- Chmod temp dirs created on localhost (mgugino@redhat.com) +- Bug 1532787 - Add empty node selector to openshift-web-console namespace + (spadgett@redhat.com) +- Remove become statements (mgugino@redhat.com) +- Bug 1527178 - installation of logging stack failed: Invalid version specified + for Elasticsearch (nhosoi@redhat.com) +- Limit host group scope on control-plane upgrades (mgugino@redhat.com) +- Refactor version and move some checks into sanity_checks.py + (mgugino@redhat.com) +- Updating tsb image names and template (ewolinet@redhat.com) +- Ensure that openshift_facts role is imported whenever we rely on + openshift_client_binary (sdodson@redhat.com) +- Add key check for facts_for_clusterrolebindings (nakayamakenjiro@gmail.com) +- Update web console template (spadgett@redhat.com) +- Use openshift_node_use_openshift_sdn when doing a containerized node upgrade + (vrutkovs@redhat.com) +- Add iptables save handler (ichavero@redhat.com) +- Fix: change import_role to include_role (mgugino@redhat.com) +- docker storage setup for ami building (jdiaz@redhat.com) +- ensure containerized bools are cast (mgugino@redhat.com) +- Properly cast crio boolean variables to bool (mgugino@redhat.com) +- Build containerized host group dynamically (mgugino@redhat.com) +- install base_packages on oo_all_hosts (mgugino@redhat.com) +- Add key existing check to collect facts for rolebidings + (nakayamakenjiro@gmail.com) +- 3.9 upgrade: remove openshift.common.service_type (vrutkovs@redhat.com) +- container-engine: move registry_auth.yml before pull (gscrivan@redhat.com) +- Fix error in variable in comment (mscherer@users.noreply.github.com) +- Switch back to dynamic include_role in logging loops (sdodson@redhat.com) +- Use Contiv version 1.2.0 (flamingo@2thebatcave.com) +- Contiv multi-master and other fixes (flamingo@2thebatcave.com) +- Add missing dependency on openshift_facts (sdodson@redhat.com) +- upgrades: set openshift_client_binary fact when running on oo_first_master + host (vrutkovs@redhat.com) +- Install web console server (spadgett@redhat.com) +- Remove become=no from various roles and tasks (mgugino@redhat.com) +- Don't overwrite node's systemd units for containerized install + (vrutkovs@redhat.com) +- Migrate to import_role for static role inclusion (sdodson@redhat.com) +- docker_upgrade_check: skip repoquery calls on containerized setups + (vrutkovs@redhat.com) +- Adding logic to disable and reenable external communication to ES during full + restart (ewolinet@redhat.com) +- Provide example on how to use osm_etcd_image in a disconnected and + containerized installation (tkarlsso@redhat.com) +- crio: create /etc/sysconfig/crio-storage (gscrivan@redhat.com) +- crio: configure proxy variables (gscrivan@redhat.com) +- Fix docker_image_availability checks (mgugino@redhat.com) +- Install node packages in one task instead of 3 (mgugino@redhat.com) +- Don't hardcode the network interface in the openshift_logging_mux role + (nkinder@redhat.com) +- failure_summary: make sure msg is always a string (vrutkovs@redhat.com) +- Adding logic to do a full cluster restart if we are incrementing our major + versions of ES (ewolinet@redhat.com) +- test_oc_scale: add more scale test cases (vrutkovs@redhat.com) +- test_oc_scale: fix test docstrings (vrutkovs@redhat.com) +- Import prerequisites.yml for OpenStack (tomas@sedovic.cz) +- Set the correct path to the openstack.conf file (tomas@sedovic.cz) +- Return a openshift_node_labels as a dict (tomas@sedovic.cz) +- Remove last of openshift_node role meta-depends (mgugino@redhat.com) +- OpenStack provisioning -- support cns. (jmencak@redhat.com) +- Fix yaml syntax error in the sample inventory (tomas@sedovic.cz) +- Adding ability to update ami drive size. (kwoodson@redhat.com) +- Add origin- prefix to ASB image (fabian@fabianism.us) +- lint issues (davis.phillips@gmail.com) +- add vsphere examples in hosts.example (davis.phillips@gmail.com) +- add template and vsphere.conf (davis.phillips@gmail.com) +- add vsphere cloud providers (davis.phillips@gmail.com) +- Fix wrong indentation (ichavero@redhat.com) +- Fix yaml indentation (ichavero@redhat.com) +- Add iptables rules for flannel (ichavero@redhat.com) + * Wed Jan 03 2018 Jenkins CD Merge Bot <smunilla@redhat.com> 3.9.0-0.16.0 - Add gluster 3.9 templates (sdodson@redhat.com) - Add in-tree CI scripts (mgugino@redhat.com) diff --git a/playbooks/aws/README.md b/playbooks/aws/README.md index d203b9cda..bdc98d1e0 100644 --- a/playbooks/aws/README.md +++ b/playbooks/aws/README.md @@ -198,3 +198,17 @@ At this point your cluster should be ready for workloads. Proceed to deploy app ### Still to come There are more enhancements that are arriving for provisioning. These will include more playbooks that enhance the provisioning capabilities. + +## Uninstall / Deprovisioning + +At this time, only deprovisioning of the output of the prerequisites step is provided. You can/must manually remove things like ELBs and scale groups before attempting to undo the work by the preprovisiong step. + +To undo the work done by the prerequisites playbook, simply call the uninstall_prerequisites.yml playbook. You should use the same inventory file and provisioning_vars.yml file that was used during provisioning. + +``` +ansible-playbook -i <previous inventory file> -e @<previous provisioning_vars file> uninstall_prerequisites.yml +``` + +This should result in removal of the security groups and VPC that were created. + +NOTE: If you want to also remove the ssh keys that were uploaded (**these ssh keys would be shared if you are running multiple clusters in the same AWS account** so we don't remove these by default) then you should add 'openshift_aws_enable_uninstall_shared_objects: True' to your provisioning_vars.yml file. diff --git a/playbooks/aws/openshift-cluster/accept.yml b/playbooks/aws/openshift-cluster/accept.yml index e7bed4f6e..46c453333 100755 --- a/playbooks/aws/openshift-cluster/accept.yml +++ b/playbooks/aws/openshift-cluster/accept.yml @@ -1,8 +1,7 @@ #!/usr/bin/ansible-playbook --- -- name: Setup the vpc and the master node group +- name: Accept nodes hosts: localhost - remote_user: root gather_facts: no tasks: - name: Alert user to variables needed - clusterid @@ -17,37 +16,7 @@ import_role: name: lib_openshift - - name: fetch masters - ec2_instance_facts: - region: "{{ openshift_aws_region | default('us-east-1') }}" - filters: - "tag:clusterid": "{{ openshift_aws_clusterid | default('default') }}" - "tag:host-type": master - instance-state-name: running - register: mastersout - retries: 20 - delay: 3 - until: "'instances' in mastersout and mastersout.instances|length > 0" - - - name: fetch new node instances - ec2_instance_facts: - region: "{{ openshift_aws_region | default('us-east-1') }}" - filters: - "tag:clusterid": "{{ openshift_aws_clusterid | default('default') }}" - "tag:host-type": node - instance-state-name: running - register: instancesout - retries: 20 - delay: 3 - until: "'instances' in instancesout and instancesout.instances|length > 0" - - - debug: - msg: "{{ instancesout.instances|map(attribute='private_dns_name') | list }}" - - - name: approve nodes - oc_adm_csr: - #approve_all: True - nodes: "{{ instancesout.instances|map(attribute='private_dns_name') | list }}" - timeout: 60 - register: nodeout - delegate_to: "{{ mastersout.instances[0].public_ip_address }}" + - name: accept nodes + import_role: + name: openshift_aws + tasks_from: accept_nodes.yml diff --git a/playbooks/aws/openshift-cluster/provision.yml b/playbooks/aws/openshift-cluster/provision.yml index 7dde60b7d..d538b862d 100644 --- a/playbooks/aws/openshift-cluster/provision.yml +++ b/playbooks/aws/openshift-cluster/provision.yml @@ -1,8 +1,7 @@ --- -- name: Setup the elb and the master node group +- name: Alert user to variables needed hosts: localhost tasks: - - name: Alert user to variables needed - clusterid debug: msg: "openshift_aws_clusterid={{ openshift_aws_clusterid | default('default') }}" @@ -11,6 +10,13 @@ debug: msg: "openshift_aws_region={{ openshift_aws_region | default('us-east-1') }}" +- import_playbook: provision_s3.yml + +- import_playbook: provision_elb.yml + +- name: Create the master node group + hosts: localhost + tasks: - name: provision cluster import_role: name: openshift_aws diff --git a/playbooks/aws/openshift-cluster/provision_elb.yml b/playbooks/aws/openshift-cluster/provision_elb.yml new file mode 100644 index 000000000..9f27dca3b --- /dev/null +++ b/playbooks/aws/openshift-cluster/provision_elb.yml @@ -0,0 +1,9 @@ +--- +- name: Create elb + hosts: localhost + connection: local + tasks: + - name: provision elb + include_role: + name: openshift_aws + tasks_from: provision_elb.yml diff --git a/playbooks/aws/openshift-cluster/provision_s3.yml b/playbooks/aws/openshift-cluster/provision_s3.yml new file mode 100644 index 000000000..45b439083 --- /dev/null +++ b/playbooks/aws/openshift-cluster/provision_s3.yml @@ -0,0 +1,10 @@ +--- +- name: Create s3 bucket + hosts: localhost + connection: local + tasks: + - name: create s3 bucket + include_role: + name: openshift_aws + tasks_from: s3.yml + when: openshift_aws_create_s3 | default(true) | bool diff --git a/playbooks/aws/openshift-cluster/uninstall_prerequisites.yml b/playbooks/aws/openshift-cluster/uninstall_prerequisites.yml new file mode 100644 index 000000000..180c2281a --- /dev/null +++ b/playbooks/aws/openshift-cluster/uninstall_prerequisites.yml @@ -0,0 +1,6 @@ +--- +- import_playbook: uninstall_sec_group.yml + +- import_playbook: uninstall_vpc.yml + +- import_playbook: uninstall_ssh_keypair.yml diff --git a/playbooks/aws/openshift-cluster/uninstall_sec_group.yml b/playbooks/aws/openshift-cluster/uninstall_sec_group.yml new file mode 100644 index 000000000..642e5b169 --- /dev/null +++ b/playbooks/aws/openshift-cluster/uninstall_sec_group.yml @@ -0,0 +1,10 @@ +--- +- hosts: localhost + connection: local + gather_facts: no + tasks: + - name: delete security groups + include_role: + name: openshift_aws + tasks_from: uninstall_security_group.yml + when: openshift_aws_create_security_groups | default(True) | bool diff --git a/playbooks/aws/openshift-cluster/uninstall_ssh_keypair.yml b/playbooks/aws/openshift-cluster/uninstall_ssh_keypair.yml new file mode 100644 index 000000000..ec9caa51b --- /dev/null +++ b/playbooks/aws/openshift-cluster/uninstall_ssh_keypair.yml @@ -0,0 +1,10 @@ +--- +- hosts: localhost + connection: local + gather_facts: no + tasks: + - name: remove ssh keypair(s) + include_role: + name: openshift_aws + tasks_from: uninstall_ssh_keys.yml + when: openshift_aws_users | default([]) | length > 0 diff --git a/playbooks/aws/openshift-cluster/uninstall_vpc.yml b/playbooks/aws/openshift-cluster/uninstall_vpc.yml new file mode 100644 index 000000000..4c988bcc5 --- /dev/null +++ b/playbooks/aws/openshift-cluster/uninstall_vpc.yml @@ -0,0 +1,10 @@ +--- +- hosts: localhost + connection: local + gather_facts: no + tasks: + - name: delete vpc + include_role: + name: openshift_aws + tasks_from: uninstall_vpc.yml + when: openshift_aws_create_vpc | default(True) | bool diff --git a/playbooks/cluster-operator/aws/infrastructure.yml b/playbooks/cluster-operator/aws/infrastructure.yml new file mode 100644 index 000000000..9669820fb --- /dev/null +++ b/playbooks/cluster-operator/aws/infrastructure.yml @@ -0,0 +1,21 @@ +--- +- name: Alert user to variables needed + hosts: localhost + tasks: + - name: Alert user to variables needed - clusterid + debug: + msg: "openshift_aws_clusterid={{ openshift_aws_clusterid | default('default') }}" + + - name: Alert user to variables needed - region + debug: + msg: "openshift_aws_region={{ openshift_aws_region | default('us-east-1') }}" + +- import_playbook: ../../aws/openshift-cluster/provision_vpc.yml + +- import_playbook: ../../aws/openshift-cluster/provision_ssh_keypair.yml + +- import_playbook: ../../aws/openshift-cluster/provision_sec_group.yml + +- import_playbook: ../../aws/openshift-cluster/provision_s3.yml + +- import_playbook: ../../aws/openshift-cluster/provision_elb.yml diff --git a/playbooks/cluster-operator/aws/roles b/playbooks/cluster-operator/aws/roles new file mode 120000 index 000000000..20c4c58cf --- /dev/null +++ b/playbooks/cluster-operator/aws/roles @@ -0,0 +1 @@ +../../../roles
\ No newline at end of file diff --git a/playbooks/common/openshift-cluster/upgrades/create_service_signer_cert.yml b/playbooks/common/openshift-cluster/upgrades/create_service_signer_cert.yml index ef8233b67..6d82fa928 100644 --- a/playbooks/common/openshift-cluster/upgrades/create_service_signer_cert.yml +++ b/playbooks/common/openshift-cluster/upgrades/create_service_signer_cert.yml @@ -17,6 +17,8 @@ - name: Create service signer certificate hosts: oo_first_master + roles: + - openshift_facts tasks: - name: Create remote temp directory for creating certs command: mktemp -d /tmp/openshift-ansible-XXXXXXX diff --git a/playbooks/common/openshift-cluster/upgrades/docker/docker_upgrade.yml b/playbooks/common/openshift-cluster/upgrades/docker/docker_upgrade.yml index ffb11670d..8392e21ee 100644 --- a/playbooks/common/openshift-cluster/upgrades/docker/docker_upgrade.yml +++ b/playbooks/common/openshift-cluster/upgrades/docker/docker_upgrade.yml @@ -51,13 +51,19 @@ - name: Drain Node for Kubelet upgrade command: > - {{ openshift_client_binary }} adm drain {{ openshift.node.nodename }} --config={{ openshift.common.config_base }}/master/admin.kubeconfig --force --delete-local-data --ignore-daemonsets + {{ hostvars[groups.oo_first_master.0]['first_master_client_binary'] }} adm drain {{ openshift.node.nodename | lower }} + --config={{ openshift.common.config_base }}/master/admin.kubeconfig + --force --delete-local-data --ignore-daemonsets + --timeout={{ openshift_upgrade_nodes_drain_timeout | default(0) }}s delegate_to: "{{ groups.oo_first_master.0 }}" when: l_docker_upgrade is defined and l_docker_upgrade | bool and inventory_hostname in groups.oo_nodes_to_upgrade register: l_docker_upgrade_drain_result until: not (l_docker_upgrade_drain_result is failed) - retries: 60 - delay: 60 + retries: "{{ 1 if ( openshift_upgrade_nodes_drain_timeout | default(0) | int ) == 0 else 0 }}" + delay: 5 + failed_when: + - l_docker_upgrade_drain_result is failed + - openshift_upgrade_nodes_drain_timeout | default(0) | int == 0 - include_tasks: tasks/upgrade.yml when: l_docker_upgrade is defined and l_docker_upgrade | bool diff --git a/playbooks/common/openshift-cluster/upgrades/init.yml b/playbooks/common/openshift-cluster/upgrades/init.yml index 8ee83819e..ba783638d 100644 --- a/playbooks/common/openshift-cluster/upgrades/init.yml +++ b/playbooks/common/openshift-cluster/upgrades/init.yml @@ -5,7 +5,8 @@ g_new_master_hosts: [] g_new_node_hosts: [] -- import_playbook: ../../../init/facts.yml +- import_playbook: ../../../init/basic_facts.yml +- import_playbook: ../../../init/cluster_facts.yml - name: Ensure firewall is not switched during upgrade hosts: "{{ l_upgrade_no_switch_firewall_hosts | default('oo_all_hosts') }}" diff --git a/playbooks/common/openshift-cluster/upgrades/initialize_nodes_to_upgrade.yml b/playbooks/common/openshift-cluster/upgrades/initialize_nodes_to_upgrade.yml index fc1cbf32a..07be0b0d4 100644 --- a/playbooks/common/openshift-cluster/upgrades/initialize_nodes_to_upgrade.yml +++ b/playbooks/common/openshift-cluster/upgrades/initialize_nodes_to_upgrade.yml @@ -31,7 +31,7 @@ with_items: " {{ groups['oo_nodes_to_config'] }}" when: - hostvars[item].openshift is defined - - hostvars[item].openshift.common.hostname in nodes_to_upgrade.results.results[0]['items'] | map(attribute='metadata.name') | list + - hostvars[item].openshift.common.hostname | lower in nodes_to_upgrade.results.results[0]['items'] | map(attribute='metadata.name') | list changed_when: false # Build up the oo_nodes_to_upgrade group, use the list filtered by label if diff --git a/playbooks/common/openshift-cluster/upgrades/post_control_plane.yml b/playbooks/common/openshift-cluster/upgrades/post_control_plane.yml index 1b57521df..f790fd98d 100644 --- a/playbooks/common/openshift-cluster/upgrades/post_control_plane.yml +++ b/playbooks/common/openshift-cluster/upgrades/post_control_plane.yml @@ -1,7 +1,13 @@ --- -############################################################################### -# Post upgrade - Upgrade default router, default registry and examples -############################################################################### +#################################################################################### +# Post upgrade - Upgrade web console, default router, default registry, and examples +#################################################################################### +- name: Upgrade web console + hosts: oo_first_master + roles: + - role: openshift_web_console + when: openshift_web_console_install | default(true) | bool + - name: Upgrade default router and default registry hosts: oo_first_master vars: diff --git a/playbooks/common/openshift-cluster/upgrades/pre/verify_upgrade_targets.yml b/playbooks/common/openshift-cluster/upgrades/pre/verify_upgrade_targets.yml index 4c1156f4b..45ddf7eea 100644 --- a/playbooks/common/openshift-cluster/upgrades/pre/verify_upgrade_targets.yml +++ b/playbooks/common/openshift-cluster/upgrades/pre/verify_upgrade_targets.yml @@ -21,7 +21,7 @@ block: - name: Check latest available OpenShift RPM version repoquery: - name: "{{ openshift_service_type }}" + name: "{{ openshift_service_type }}{{ '-' ~ openshift_release ~ '*' if openshift_release is defined else '' }}" ignore_excluders: true register: repoquery_out diff --git a/playbooks/common/openshift-cluster/upgrades/upgrade_control_plane.yml b/playbooks/common/openshift-cluster/upgrades/upgrade_control_plane.yml index 412075d41..e89f06f17 100644 --- a/playbooks/common/openshift-cluster/upgrades/upgrade_control_plane.yml +++ b/playbooks/common/openshift-cluster/upgrades/upgrade_control_plane.yml @@ -22,6 +22,8 @@ # See: https://github.com/openshift/origin/pull/14625#issuecomment-308467060 - name: Pre master upgrade - Upgrade all storage hosts: oo_first_master + roles: + - openshift_facts tasks: - name: Upgrade all storage command: > @@ -49,10 +51,9 @@ vars: openshift_master_ha: "{{ groups.oo_masters_to_config | length > 1 }}" serial: 1 + roles: + - openshift_facts tasks: - - import_role: - name: openshift_facts - # Run the pre-upgrade hook if defined: - debug: msg="Running master pre-upgrade hook {{ openshift_master_upgrade_pre_hook }}" when: openshift_master_upgrade_pre_hook is defined @@ -127,6 +128,7 @@ hosts: oo_masters_to_config roles: - { role: openshift_cli } + - { role: openshift_facts } vars: __master_shared_resource_viewer_file: "shared_resource_viewer_role.yaml" tasks: @@ -289,12 +291,18 @@ - name: Drain Node for Kubelet upgrade command: > - {{ hostvars[groups.oo_first_master.0]['first_master_client_binary'] }} adm drain {{ openshift.node.nodename | lower }} --config={{ openshift.common.config_base }}/master/admin.kubeconfig --force --delete-local-data --ignore-daemonsets + {{ hostvars[groups.oo_first_master.0]['first_master_client_binary'] }} adm drain {{ openshift.node.nodename | lower }} + --config={{ openshift.common.config_base }}/master/admin.kubeconfig + --force --delete-local-data --ignore-daemonsets + --timeout={{ openshift_upgrade_nodes_drain_timeout | default(0) }}s delegate_to: "{{ groups.oo_first_master.0 }}" register: l_upgrade_control_plane_drain_result until: not (l_upgrade_control_plane_drain_result is failed) - retries: 60 - delay: 60 + retries: "{{ 1 if ( openshift_upgrade_nodes_drain_timeout | default(0) | int ) == 0 else 0 }}" + delay: 5 + failed_when: + - l_upgrade_control_plane_drain_result is failed + - openshift_upgrade_nodes_drain_timeout | default(0) | int == 0 roles: - openshift_facts diff --git a/playbooks/common/openshift-cluster/upgrades/upgrade_nodes.yml b/playbooks/common/openshift-cluster/upgrades/upgrade_nodes.yml index 464af3ae6..850442b3b 100644 --- a/playbooks/common/openshift-cluster/upgrades/upgrade_nodes.yml +++ b/playbooks/common/openshift-cluster/upgrades/upgrade_nodes.yml @@ -33,12 +33,18 @@ - name: Drain Node for Kubelet upgrade command: > - {{ hostvars[groups.oo_first_master.0]['first_master_client_binary'] }} adm drain {{ openshift.node.nodename | lower }} --config={{ openshift.common.config_base }}/master/admin.kubeconfig --force --delete-local-data --ignore-daemonsets + {{ hostvars[groups.oo_first_master.0]['first_master_client_binary'] }} adm drain {{ openshift.node.nodename | lower }} + --config={{ openshift.common.config_base }}/master/admin.kubeconfig + --force --delete-local-data --ignore-daemonsets + --timeout={{ openshift_upgrade_nodes_drain_timeout | default(0) }}s delegate_to: "{{ groups.oo_first_master.0 }}" register: l_upgrade_nodes_drain_result until: not (l_upgrade_nodes_drain_result is failed) - retries: 60 - delay: 60 + retries: "{{ 1 if ( openshift_upgrade_nodes_drain_timeout | default(0) | int ) == 0 else 0 }}" + delay: 5 + failed_when: + - l_upgrade_nodes_drain_result is failed + - openshift_upgrade_nodes_drain_timeout | default(0) | int == 0 post_tasks: - import_role: diff --git a/playbooks/common/openshift-cluster/upgrades/upgrade_scale_group.yml b/playbooks/common/openshift-cluster/upgrades/upgrade_scale_group.yml index 6d59bfd0b..e259b5d09 100644 --- a/playbooks/common/openshift-cluster/upgrades/upgrade_scale_group.yml +++ b/playbooks/common/openshift-cluster/upgrades/upgrade_scale_group.yml @@ -50,11 +50,11 @@ delegate_to: "{{ groups.oo_first_master.0 }}" register: l_upgrade_nodes_drain_result until: not (l_upgrade_nodes_drain_result is failed) - retries: "{{ 1 if openshift_upgrade_nodes_drain_timeout | default(0) == '0' else 0 | int }}" + retries: "{{ 1 if ( openshift_upgrade_nodes_drain_timeout | default(0) | int ) == 0 else 0 }}" delay: 5 failed_when: - l_upgrade_nodes_drain_result is failed - - openshift_upgrade_nodes_drain_timeout | default(0) == '0' + - openshift_upgrade_nodes_drain_timeout | default(0) | int == 0 # Alright, let's clean up! - name: clean up the old scale group diff --git a/playbooks/common/openshift-cluster/upgrades/v3_6/upgrade_control_plane.yml b/playbooks/common/openshift-cluster/upgrades/v3_6/upgrade_control_plane.yml index eb5f07ae0..d88880140 100644 --- a/playbooks/common/openshift-cluster/upgrades/v3_6/upgrade_control_plane.yml +++ b/playbooks/common/openshift-cluster/upgrades/v3_6/upgrade_control_plane.yml @@ -14,7 +14,7 @@ - import_playbook: ../init.yml vars: l_upgrade_no_switch_firewall_hosts: "oo_masters_to_config:oo_etcd_to_config:oo_lb_to_config" - l_upgrade_non_node_hosts: "oo_masters_to_config:oo_etcd_to_config:oo_lb_to_config" + l_init_fact_hosts: "oo_masters_to_config:oo_etcd_to_config:oo_lb_to_config" - name: Configure the upgrade target for the common upgrade tasks hosts: oo_masters_to_config:oo_etcd_to_config:oo_lb_to_config diff --git a/playbooks/common/openshift-cluster/upgrades/v3_7/upgrade_control_plane.yml b/playbooks/common/openshift-cluster/upgrades/v3_7/upgrade_control_plane.yml index 8d42e4c91..ce069e2d0 100644 --- a/playbooks/common/openshift-cluster/upgrades/v3_7/upgrade_control_plane.yml +++ b/playbooks/common/openshift-cluster/upgrades/v3_7/upgrade_control_plane.yml @@ -14,7 +14,7 @@ - import_playbook: ../init.yml vars: l_upgrade_no_switch_firewall_hosts: "oo_masters_to_config:oo_etcd_to_config:oo_lb_to_config" - l_upgrade_non_node_hosts: "oo_masters_to_config:oo_etcd_to_config:oo_lb_to_config" + l_init_fact_hosts: "oo_masters_to_config:oo_etcd_to_config:oo_lb_to_config" - name: Configure the upgrade target for the common upgrade tasks hosts: oo_masters_to_config:oo_etcd_to_config:oo_lb_to_config diff --git a/playbooks/common/openshift-cluster/upgrades/v3_7/validator.yml b/playbooks/common/openshift-cluster/upgrades/v3_7/validator.yml index 49e691352..9c7688981 100644 --- a/playbooks/common/openshift-cluster/upgrades/v3_7/validator.yml +++ b/playbooks/common/openshift-cluster/upgrades/v3_7/validator.yml @@ -7,6 +7,7 @@ hosts: oo_first_master roles: - { role: lib_openshift } + - { role: openshift_facts } tasks: - name: Check for invalid namespaces and SDN errors diff --git a/playbooks/common/openshift-cluster/upgrades/v3_8/upgrade.yml b/playbooks/common/openshift-cluster/upgrades/v3_8/upgrade.yml index 0f74e0137..a9bf354cc 100644 --- a/playbooks/common/openshift-cluster/upgrades/v3_8/upgrade.yml +++ b/playbooks/common/openshift-cluster/upgrades/v3_8/upgrade.yml @@ -35,8 +35,6 @@ # Pre-upgrade completed - import_playbook: ../upgrade_control_plane.yml - vars: - master_config_hook: "v3_7/master_config_upgrade.yml" # All controllers must be stopped at the same time then restarted - name: Cycle all controller services to force new leader election mode diff --git a/playbooks/common/openshift-cluster/upgrades/v3_8/upgrade_control_plane.yml b/playbooks/common/openshift-cluster/upgrades/v3_8/upgrade_control_plane.yml index a2f316c25..3f26a6297 100644 --- a/playbooks/common/openshift-cluster/upgrades/v3_8/upgrade_control_plane.yml +++ b/playbooks/common/openshift-cluster/upgrades/v3_8/upgrade_control_plane.yml @@ -14,7 +14,8 @@ - import_playbook: ../init.yml vars: l_upgrade_no_switch_firewall_hosts: "oo_masters_to_config:oo_etcd_to_config:oo_lb_to_config" - l_upgrade_non_node_hosts: "oo_masters_to_config:oo_etcd_to_config:oo_lb_to_config" + l_init_fact_hosts: "oo_masters_to_config:oo_etcd_to_config:oo_lb_to_config" + when: not skip_version_info | default(false) - name: Configure the upgrade target for the common upgrade tasks hosts: oo_masters_to_config:oo_etcd_to_config:oo_lb_to_config @@ -47,8 +48,6 @@ # Pre-upgrade completed - import_playbook: ../upgrade_control_plane.yml - vars: - master_config_hook: "v3_7/master_config_upgrade.yml" # All controllers must be stopped at the same time then restarted - name: Cycle all controller services to force new leader election mode diff --git a/playbooks/common/openshift-cluster/upgrades/v3_9/master_config_upgrade.yml b/playbooks/common/openshift-cluster/upgrades/v3_9/master_config_upgrade.yml index 1d4d1919c..ed97d539c 100644 --- a/playbooks/common/openshift-cluster/upgrades/v3_9/master_config_upgrade.yml +++ b/playbooks/common/openshift-cluster/upgrades/v3_9/master_config_upgrade.yml @@ -1,20 +1 @@ --- -- modify_yaml: - dest: "{{ openshift.common.config_base}}/master/master-config.yaml" - yaml_key: 'controllerConfig.election.lockName' - yaml_value: 'openshift-master-controllers' - -- modify_yaml: - dest: "{{ openshift.common.config_base}}/master/master-config.yaml" - yaml_key: 'controllerConfig.serviceServingCert.signer.certFile' - yaml_value: service-signer.crt - -- modify_yaml: - dest: "{{ openshift.common.config_base}}/master/master-config.yaml" - yaml_key: 'controllerConfig.serviceServingCert.signer.keyFile' - yaml_value: service-signer.key - -- modify_yaml: - dest: "{{ openshift.common.config_base }}/master/master-config.yaml" - yaml_key: servingInfo.clientCA - yaml_value: ca.crt diff --git a/playbooks/common/openshift-cluster/upgrades/v3_9/upgrade.yml b/playbooks/common/openshift-cluster/upgrades/v3_9/upgrade.yml index 0aea5069d..20e0c165e 100644 --- a/playbooks/common/openshift-cluster/upgrades/v3_9/upgrade.yml +++ b/playbooks/common/openshift-cluster/upgrades/v3_9/upgrade.yml @@ -10,6 +10,7 @@ - set_fact: openshift_upgrade_target: '3.9' openshift_upgrade_min: '3.7' + openshift_release: '3.9' - import_playbook: ../pre/config.yml vars: @@ -31,8 +32,6 @@ # Pre-upgrade completed - import_playbook: ../upgrade_control_plane.yml - vars: - master_config_hook: "v3_7/master_config_upgrade.yml" # All controllers must be stopped at the same time then restarted - name: Cycle all controller services to force new leader election mode @@ -41,13 +40,13 @@ roles: - role: openshift_facts tasks: - - name: Stop {{ openshift.common.service_type }}-master-controllers + - name: Stop {{ openshift_service_type }}-master-controllers systemd: - name: "{{ openshift.common.service_type }}-master-controllers" + name: "{{ openshift_service_type }}-master-controllers" state: stopped - - name: Start {{ openshift.common.service_type }}-master-controllers + - name: Start {{ openshift_service_type }}-master-controllers systemd: - name: "{{ openshift.common.service_type }}-master-controllers" + name: "{{ openshift_service_type }}-master-controllers" state: started - import_playbook: ../upgrade_nodes.yml diff --git a/playbooks/common/openshift-cluster/upgrades/v3_9/upgrade_control_plane.yml b/playbooks/common/openshift-cluster/upgrades/v3_9/upgrade_control_plane.yml index ef9871008..0f48725f6 100644 --- a/playbooks/common/openshift-cluster/upgrades/v3_9/upgrade_control_plane.yml +++ b/playbooks/common/openshift-cluster/upgrades/v3_9/upgrade_control_plane.yml @@ -14,14 +14,20 @@ - import_playbook: ../init.yml vars: l_upgrade_no_switch_firewall_hosts: "oo_masters_to_config:oo_etcd_to_config:oo_lb_to_config" - l_upgrade_non_node_hosts: "oo_masters_to_config:oo_etcd_to_config:oo_lb_to_config" + l_init_fact_hosts: "oo_masters_to_config:oo_etcd_to_config:oo_lb_to_config" -- name: Configure the upgrade target for the common upgrade tasks +## Check to see if they're running 3.7 and if so upgrade them to 3.8 on control plan +## If they've specified pkg_version or image_tag preserve that for later use +- name: Configure the upgrade target for the common upgrade tasks 3.8 hosts: oo_masters_to_config:oo_etcd_to_config:oo_lb_to_config tasks: - set_fact: - openshift_upgrade_target: '3.9' + openshift_upgrade_target: '3.8' openshift_upgrade_min: '3.7' + openshift_release: '3.8' + _requested_pkg_version: "{{openshift_pkg_version if openshift_pkg_version is defined else omit }}" + _requested_image_tag: "{{openshift_image_tag if openshift_image_tag is defined else omit }}" + when: hostvars[groups.oo_first_master.0].openshift_currently_installed_version | version_compare('3.8','<') - import_playbook: ../pre/config.yml # These vars a meant to exclude oo_nodes from plays that would otherwise include @@ -35,21 +41,57 @@ l_upgrade_verify_targets_hosts: "oo_masters_to_config" l_upgrade_docker_target_hosts: "oo_masters_to_config:oo_etcd_to_config" l_upgrade_excluder_hosts: "oo_masters_to_config" + when: hostvars[groups.oo_first_master.0].openshift_currently_installed_version | version_compare('3.8','<') -- import_playbook: validator.yml - -- name: Flag pre-upgrade checks complete for hosts without errors +- name: Flag pre-upgrade checks complete for hosts without errors 3.8 hosts: oo_masters_to_config:oo_etcd_to_config tasks: - set_fact: pre_upgrade_complete: True + when: hostvars[groups.oo_first_master.0].openshift_currently_installed_version | version_compare('3.8','<') # Pre-upgrade completed +- import_playbook: ../upgrade_control_plane.yml + vars: + openshift_release: '3.8' + when: hostvars[groups.oo_first_master.0].openshift_currently_installed_version | version_compare('3.8','<') + +## 3.8 upgrade complete we should now be able to upgrade to 3.9 + +- name: Configure the upgrade target for the common upgrade tasks 3.9 + hosts: oo_masters_to_config:oo_etcd_to_config:oo_lb_to_config + tasks: + - meta: clear_facts + - set_fact: + openshift_upgrade_target: '3.9' + openshift_upgrade_min: '3.8' + openshift_release: '3.9' + openshift_pkg_version: "{{ _requested_pkg_version | default ('-3.9*') }}" + openshift_image_tag: "{{ _requested_image_tag | default('v3.9') }}" + +- import_playbook: ../pre/config.yml + # These vars a meant to exclude oo_nodes from plays that would otherwise include + # them by default. + vars: + l_openshift_version_set_hosts: "oo_etcd_to_config:oo_masters_to_config:!oo_first_master" + l_openshift_version_check_hosts: "oo_masters_to_config:!oo_first_master" + l_upgrade_repo_hosts: "oo_masters_to_config:oo_etcd_to_config:oo_lb_to_config" + l_upgrade_no_proxy_hosts: "oo_masters_to_config" + l_upgrade_health_check_hosts: "oo_masters_to_config:oo_etcd_to_config:oo_lb_to_config" + l_upgrade_verify_targets_hosts: "oo_masters_to_config" + l_upgrade_docker_target_hosts: "oo_masters_to_config:oo_etcd_to_config" + l_upgrade_excluder_hosts: "oo_masters_to_config" + +- name: Flag pre-upgrade checks complete for hosts without errors + hosts: oo_masters_to_config:oo_etcd_to_config + tasks: + - set_fact: + pre_upgrade_complete: True - import_playbook: ../upgrade_control_plane.yml vars: - master_config_hook: "v3_7/master_config_upgrade.yml" + openshift_release: '3.9' # All controllers must be stopped at the same time then restarted - name: Cycle all controller services to force new leader election mode @@ -58,13 +100,13 @@ roles: - role: openshift_facts tasks: - - name: Stop {{ openshift.common.service_type }}-master-controllers + - name: Stop {{ openshift_service_type }}-master-controllers systemd: - name: "{{ openshift.common.service_type }}-master-controllers" + name: "{{ openshift_service_type }}-master-controllers" state: stopped - - name: Start {{ openshift.common.service_type }}-master-controllers + - name: Start {{ openshift_service_type }}-master-controllers systemd: - name: "{{ openshift.common.service_type }}-master-controllers" + name: "{{ openshift_service_type }}-master-controllers" state: started - import_playbook: ../post_control_plane.yml diff --git a/playbooks/common/openshift-cluster/upgrades/v3_9/upgrade_nodes.yml b/playbooks/common/openshift-cluster/upgrades/v3_9/upgrade_nodes.yml index 1d1b255c1..859b1d88b 100644 --- a/playbooks/common/openshift-cluster/upgrades/v3_9/upgrade_nodes.yml +++ b/playbooks/common/openshift-cluster/upgrades/v3_9/upgrade_nodes.yml @@ -12,6 +12,7 @@ - set_fact: openshift_upgrade_target: '3.9' openshift_upgrade_min: '3.7' + openshift_release: '3.9' - import_playbook: ../pre/config.yml vars: diff --git a/playbooks/common/openshift-cluster/upgrades/v3_9/validator.yml b/playbooks/common/openshift-cluster/upgrades/v3_9/validator.yml index 4bd2d87b1..d8540abfb 100644 --- a/playbooks/common/openshift-cluster/upgrades/v3_9/validator.yml +++ b/playbooks/common/openshift-cluster/upgrades/v3_9/validator.yml @@ -1,5 +1,5 @@ --- -- name: Verify 3.9 specific upgrade checks +- name: Verify 3.8 specific upgrade checks hosts: oo_first_master roles: - { role: lib_openshift } diff --git a/playbooks/container-runtime/private/build_container_groups.yml b/playbooks/container-runtime/private/build_container_groups.yml index 7fd60743c..a2361d50c 100644 --- a/playbooks/container-runtime/private/build_container_groups.yml +++ b/playbooks/container-runtime/private/build_container_groups.yml @@ -3,4 +3,4 @@ hosts: oo_all_hosts:!oo_nodes_to_config tasks: - group_by: - key: oo_hosts_containerized_managed_{{ (containerized | default(False)) | ternary('true','false') }} + key: oo_hosts_containerized_managed_{{ (openshift_is_containerized | default(False)) | ternary('true','false') }} diff --git a/playbooks/container-runtime/private/config.yml b/playbooks/container-runtime/private/config.yml index 7a49adcf0..817a8bf30 100644 --- a/playbooks/container-runtime/private/config.yml +++ b/playbooks/container-runtime/private/config.yml @@ -1,7 +1,11 @@ --- +# l_scale_up_hosts may be passed in via prerequisites.yml during scaleup plays. + - import_playbook: build_container_groups.yml -- hosts: oo_nodes_to_config:oo_hosts_containerized_managed_true +- hosts: "{{ l_scale_up_hosts | default(l_default_container_runtime_hosts) }}" + vars: + l_default_container_runtime_hosts: "oo_nodes_to_config:oo_hosts_containerized_managed_true" roles: - role: container_runtime tasks: diff --git a/playbooks/container-runtime/private/setup_storage.yml b/playbooks/container-runtime/private/setup_storage.yml index a6d396270..65630be62 100644 --- a/playbooks/container-runtime/private/setup_storage.yml +++ b/playbooks/container-runtime/private/setup_storage.yml @@ -1,8 +1,11 @@ --- +# l_scale_up_hosts may be passed in via prerequisites.yml during scaleup plays. + - import_playbook: build_container_groups.yml -- hosts: oo_nodes_to_config:oo_hosts_containerized_managed_true +- hosts: "{{ l_scale_up_hosts | default(l_default_container_storage_hosts) }}" vars: + l_default_container_storage_hosts: "oo_nodes_to_config:oo_hosts_containerized_managed_true" l_chg_temp: "{{ hostvars[groups['oo_first_master'][0]]['openshift_containerized_host_groups'] | default([]) }}" l_containerized_host_groups: "{{ (['oo_nodes_to_config'] | union(l_chg_temp)) | join(':') }}" # role: container_runtime is necessary here to bring role default variables diff --git a/playbooks/init/base_packages.yml b/playbooks/init/base_packages.yml index 15b3dd492..e1052fb6c 100644 --- a/playbooks/init/base_packages.yml +++ b/playbooks/init/base_packages.yml @@ -1,6 +1,8 @@ --- +# l_scale_up_hosts may be passed in via prerequisites.yml during scaleup plays. + - name: Install packages necessary for installer - hosts: oo_all_hosts + hosts: "{{ l_scale_up_hosts | default('oo_all_hosts') }}" any_errors_fatal: true tasks: - when: diff --git a/playbooks/init/facts.yml b/playbooks/init/basic_facts.yml index 8e4206948..06a4e7291 100644 --- a/playbooks/init/facts.yml +++ b/playbooks/init/basic_facts.yml @@ -4,15 +4,13 @@ any_errors_fatal: true tasks: -- name: Initialize host facts - # l_upgrade_non_node_hosts is passed in via play during control-plane-only - # upgrades; otherwise oo_all_hosts is used. - hosts: "{{ l_upgrade_non_node_hosts | default('oo_all_hosts') }}" +- name: Initialize basic host facts + # l_init_fact_hosts is passed in via play during control-plane-only + # upgrades and scale-up plays; otherwise oo_all_hosts is used. + hosts: "{{ l_init_fact_hosts | default('oo_all_hosts') }}" + roles: + - role: openshift_facts tasks: - - name: load openshift_facts module - import_role: - name: openshift_facts - # TODO: Should this role be refactored into health_checks?? - name: Run openshift_sanitize_inventory to set variables import_role: @@ -58,41 +56,6 @@ - l_atomic_docker_version.stdout | replace('"', '') is version_compare('1.12','>=') msg: Installation on Atomic Host requires Docker 1.12 or later. Please upgrade and restart the Atomic Host. - - name: Gather Cluster facts - openshift_facts: - role: common - local_facts: - deployment_type: "{{ openshift_deployment_type }}" - deployment_subtype: "{{ openshift_deployment_subtype | default(None) }}" - hostname: "{{ openshift_hostname | default(None) }}" - ip: "{{ openshift_ip | default(None) }}" - public_hostname: "{{ openshift_public_hostname | default(None) }}" - public_ip: "{{ openshift_public_ip | default(None) }}" - portal_net: "{{ openshift_portal_net | default(openshift_master_portal_net) | default(None) }}" - http_proxy: "{{ openshift_http_proxy | default(None) }}" - https_proxy: "{{ openshift_https_proxy | default(None) }}" - no_proxy: "{{ openshift_no_proxy | default(None) }}" - generate_no_proxy_hosts: "{{ openshift_generate_no_proxy_hosts | default(True) }}" - - - name: Set fact of no_proxy_internal_hostnames - openshift_facts: - role: common - local_facts: - no_proxy_internal_hostnames: "{{ hostvars | lib_utils_oo_select_keys(groups['oo_nodes_to_config'] - | union(groups['oo_masters_to_config']) - | union(groups['oo_etcd_to_config'] | default([]))) - | lib_utils_oo_collect('openshift.common.hostname') | default([]) | join (',') - }}" - when: - - openshift_http_proxy is defined or openshift_https_proxy is defined - - openshift_generate_no_proxy_hosts | default(True) | bool - - - name: Initialize openshift.node.sdn_mtu - openshift_facts: - role: node - local_facts: - sdn_mtu: "{{ openshift_node_sdn_mtu | default(None) }}" - - name: Initialize special first-master variables hosts: oo_first_master roles: diff --git a/playbooks/init/cluster_facts.yml b/playbooks/init/cluster_facts.yml new file mode 100644 index 000000000..636679e32 --- /dev/null +++ b/playbooks/init/cluster_facts.yml @@ -0,0 +1,42 @@ +--- +- name: Initialize cluster facts + # l_init_fact_hosts is passed in via play during control-plane-only + # upgrades and scale-up plays; otherwise oo_all_hosts is used. + hosts: "{{ l_init_fact_hosts | default('oo_all_hosts') }}" + roles: + - role: openshift_facts + tasks: + - name: Gather Cluster facts + openshift_facts: + role: common + local_facts: + deployment_type: "{{ openshift_deployment_type }}" + deployment_subtype: "{{ openshift_deployment_subtype | default(None) }}" + hostname: "{{ openshift_hostname | default(None) }}" + ip: "{{ openshift_ip | default(None) }}" + public_hostname: "{{ openshift_public_hostname | default(None) }}" + public_ip: "{{ openshift_public_ip | default(None) }}" + portal_net: "{{ openshift_portal_net | default(openshift_master_portal_net) | default(None) }}" + http_proxy: "{{ openshift_http_proxy | default(None) }}" + https_proxy: "{{ openshift_https_proxy | default(None) }}" + no_proxy: "{{ openshift_no_proxy | default(None) }}" + generate_no_proxy_hosts: "{{ openshift_generate_no_proxy_hosts | default(True) }}" + + - name: Set fact of no_proxy_internal_hostnames + openshift_facts: + role: common + local_facts: + no_proxy_internal_hostnames: "{{ hostvars | lib_utils_oo_select_keys(groups['oo_nodes_to_config'] + | union(groups['oo_masters_to_config']) + | union(groups['oo_etcd_to_config'] | default([]))) + | lib_utils_oo_collect('openshift.common.hostname') | default([]) | join (',') + }}" + when: + - openshift_http_proxy is defined or openshift_https_proxy is defined + - openshift_generate_no_proxy_hosts | default(True) | bool + + - name: Initialize openshift.node.sdn_mtu + openshift_facts: + role: node + local_facts: + sdn_mtu: "{{ openshift_node_sdn_mtu | default(None) }}" diff --git a/playbooks/init/main.yml b/playbooks/init/main.yml index 8a3f4682d..9886691e0 100644 --- a/playbooks/init/main.yml +++ b/playbooks/init/main.yml @@ -1,4 +1,7 @@ --- +# skip_verison and l_install_base_packages are passed in via prerequistes.yml. +# skip_sanity_checks is passed in via openshift-node/private/image_prep.yml + - name: Initialization Checkpoint Start hosts: all gather_facts: false @@ -15,7 +18,13 @@ - import_playbook: evaluate_groups.yml -- import_playbook: facts.yml +- import_playbook: basic_facts.yml + +# base_packages needs to be setup for openshift_facts.py to run correctly. +- import_playbook: base_packages.yml + when: l_install_base_packages | default(False) | bool + +- import_playbook: cluster_facts.yml - import_playbook: version.yml when: not (skip_verison | default(False)) diff --git a/playbooks/init/repos.yml b/playbooks/init/repos.yml index 667f38ddd..655a7e83a 100644 --- a/playbooks/init/repos.yml +++ b/playbooks/init/repos.yml @@ -1,6 +1,8 @@ --- +# l_scale_up_hosts may be passed in via prerequisites.yml during scaleup plays. + - name: Setup yum repositories for all hosts - hosts: oo_all_hosts + hosts: "{{ l_scale_up_hosts | default('oo_all_hosts') }}" gather_facts: no tasks: - name: subscribe instances to Red Hat Subscription Manager diff --git a/playbooks/init/sanity_checks.yml b/playbooks/init/sanity_checks.yml index 52bcf42c0..fbbb3f8fb 100644 --- a/playbooks/init/sanity_checks.yml +++ b/playbooks/init/sanity_checks.yml @@ -1,4 +1,5 @@ --- +# l_sanity_check_hosts may be passed in during scale-up plays - name: Verify Requirements hosts: oo_first_master roles: @@ -11,5 +12,5 @@ # Thus, sanity_checks cannot gather new information about any hosts. - name: Run variable sanity checks sanity_checks: - check_hosts: "{{ groups['oo_all_hosts'] }}" + check_hosts: "{{ l_sanity_check_hosts | default(groups['oo_all_hosts']) }}" run_once: True diff --git a/playbooks/init/validate_hostnames.yml b/playbooks/init/validate_hostnames.yml index 86e0b2416..b49f7dd08 100644 --- a/playbooks/init/validate_hostnames.yml +++ b/playbooks/init/validate_hostnames.yml @@ -25,7 +25,7 @@ when: - lookupip.stdout != '127.0.0.1' - lookupip.stdout not in ansible_all_ipv4_addresses - - openshift_hostname_check | default(true) + - openshift_hostname_check | default(true) | bool - name: Validate openshift_ip exists on node when defined fail: @@ -40,4 +40,4 @@ when: - openshift_ip is defined - openshift_ip not in ansible_all_ipv4_addresses - - openshift_ip_check | default(true) + - openshift_ip_check | default(true) | bool diff --git a/playbooks/init/version.yml b/playbooks/init/version.yml index 8d1d61fde..962ee7220 100644 --- a/playbooks/init/version.yml +++ b/playbooks/init/version.yml @@ -6,7 +6,7 @@ - include_role: name: openshift_version tasks_from: first_master.yml - - debug: msg="openshift_pkg_version set to {{ openshift_pkg_version }}" + - debug: msg="openshift_pkg_version set to {{ openshift_pkg_version | default('') }}" # NOTE: We set this even on etcd hosts as they may also later run as masters, # and we don't want to install wrong version of docker and have to downgrade @@ -16,7 +16,7 @@ vars: l_default_version_set_hosts: "oo_etcd_to_config:oo_nodes_to_config:oo_masters_to_config:!oo_first_master" l_first_master_openshift_version: "{{ hostvars[groups.oo_first_master.0].openshift_version }}" - l_first_master_openshift_pkg_version: "{{ hostvars[groups.oo_first_master.0].openshift_pkg_version }}" + l_first_master_openshift_pkg_version: "{{ hostvars[groups.oo_first_master.0].openshift_pkg_version | default('') }}" l_first_master_openshift_image_tag: "{{ hostvars[groups.oo_first_master.0].openshift_image_tag}}" tasks: - set_fact: diff --git a/playbooks/openshift-checks/adhoc.yml b/playbooks/openshift-checks/adhoc.yml index 414090733..249222ae4 100644 --- a/playbooks/openshift-checks/adhoc.yml +++ b/playbooks/openshift-checks/adhoc.yml @@ -11,6 +11,7 @@ # usage. Running this play only in localhost speeds up execution. hosts: localhost connection: local + gather_facts: false roles: - openshift_health_checker vars: diff --git a/playbooks/openshift-etcd/upgrade.yml b/playbooks/openshift-etcd/upgrade.yml index ccc797527..77999d92c 100644 --- a/playbooks/openshift-etcd/upgrade.yml +++ b/playbooks/openshift-etcd/upgrade.yml @@ -1,4 +1,8 @@ --- -- import_playbook: ../init/evaluate_groups.yml +- import_playbook: ../init/main.yml + vars: + skip_verison: True + l_init_fact_hosts: "oo_masters_to_config:oo_etcd_to_config:oo_lb_to_config" + l_sanity_check_hosts: "{{ groups['oo_etcd_to_config'] | union(groups['oo_masters_to_config']) }}" - import_playbook: private/upgrade_main.yml diff --git a/playbooks/openshift-grafana/config.yml b/playbooks/openshift-grafana/config.yml new file mode 100644 index 000000000..c7814207c --- /dev/null +++ b/playbooks/openshift-grafana/config.yml @@ -0,0 +1,4 @@ +--- +- import_playbook: ../init/main.yml + +- import_playbook: private/config.yml diff --git a/playbooks/openshift-grafana/private/config.yml b/playbooks/openshift-grafana/private/config.yml new file mode 100644 index 000000000..ac753d63b --- /dev/null +++ b/playbooks/openshift-grafana/private/config.yml @@ -0,0 +1,6 @@ +--- +- name: Deploy grafana server + hosts: masters + tasks: + - include_role: + name: openshift_grafana diff --git a/playbooks/openshift-grafana/private/filter_plugins b/playbooks/openshift-grafana/private/filter_plugins new file mode 120000 index 000000000..99a95e4ca --- /dev/null +++ b/playbooks/openshift-grafana/private/filter_plugins @@ -0,0 +1 @@ +../../../filter_plugins
\ No newline at end of file diff --git a/playbooks/openshift-grafana/private/lookup_plugins b/playbooks/openshift-grafana/private/lookup_plugins new file mode 120000 index 000000000..ac79701db --- /dev/null +++ b/playbooks/openshift-grafana/private/lookup_plugins @@ -0,0 +1 @@ +../../../lookup_plugins
\ No newline at end of file diff --git a/playbooks/openshift-grafana/private/roles b/playbooks/openshift-grafana/private/roles new file mode 120000 index 000000000..e2b799b9d --- /dev/null +++ b/playbooks/openshift-grafana/private/roles @@ -0,0 +1 @@ +../../../roles/
\ No newline at end of file diff --git a/playbooks/openshift-loadbalancer/private/config.yml b/playbooks/openshift-loadbalancer/private/config.yml index 54c8483c8..4a83dd955 100644 --- a/playbooks/openshift-loadbalancer/private/config.yml +++ b/playbooks/openshift-loadbalancer/private/config.yml @@ -24,7 +24,7 @@ openshift_use_nuage | default(false), nuage_mon_rest_server_port | default(none))) + openshift_loadbalancer_additional_backends | default([]) }}" - openshift_image_tag: "{{ hostvars[groups.oo_first_master.0].openshift_image_tag }}" + openshift_image_tag: "{{ hostvars[groups.oo_masters_to_config.0].openshift_image_tag }}" roles: - role: openshift_loadbalancer - role: tuned diff --git a/playbooks/openshift-master/private/certificates-backup.yml b/playbooks/openshift-master/private/certificates-backup.yml index 4dbc041b0..56af18ca7 100644 --- a/playbooks/openshift-master/private/certificates-backup.yml +++ b/playbooks/openshift-master/private/certificates-backup.yml @@ -28,6 +28,7 @@ path: "{{ openshift.common.config_base }}/master/{{ item }}" state: absent with_items: + # certificates_to_synchronize is a custom filter in lib_utils - "{{ hostvars[inventory_hostname] | certificates_to_synchronize(include_keys=false, include_ca=false) }}" - "etcd.server.crt" - "etcd.server.key" diff --git a/playbooks/openshift-master/scaleup.yml b/playbooks/openshift-master/scaleup.yml index 7d31340a2..09e205afc 100644 --- a/playbooks/openshift-master/scaleup.yml +++ b/playbooks/openshift-master/scaleup.yml @@ -1,22 +1,43 @@ --- - import_playbook: ../init/evaluate_groups.yml -- name: Ensure there are new_masters or new_nodes +- name: Ensure there are new_masters and new_nodes hosts: localhost connection: local gather_facts: no tasks: - fail: + # new_masters must be part of new_nodes as well; otherwise if new_nodes + # is not present, oo_nodes_to_config will contain all existing nodes. msg: > - Detected no new_masters or no new_nodes in inventory. Please - add hosts to the new_masters and new_nodes host groups to add - masters. - when: - - g_new_master_hosts | default([]) | length == 0 - - g_new_node_hosts | default([]) | length == 0 + Detected no new_masters and/or no new_nodes in inventory. New + masters must be part of both new_masters and new_nodes groups. + If you are adding just new_nodes, use the + playbooks/openshift-node/scaleup.yml play. + when: > + g_new_master_hosts | default([]) | length == 0 + or g_new_node_hosts | default([]) | length == 0 -# Need a better way to do the above check for node without -# running evaluate_groups and init/main.yml -- import_playbook: ../init/main.yml +- name: Ensure there are new_masters and new_nodes + hosts: oo_masters_to_config + connection: local + gather_facts: no + tasks: + - fail: + # new_masters must be part of new_nodes as well; + msg: > + Each host in new_masters must also appear in new_nodes + when: inventory_hostname not in groups['oo_nodes_to_config'] + +- import_playbook: ../prerequisites.yml + vars: + l_scale_up_hosts: "oo_nodes_to_config:oo_masters_to_config" + l_init_fact_hosts: "oo_masters_to_config:oo_etcd_to_config:oo_lb_to_config:oo_nodes_to_config" + l_sanity_check_hosts: "{{ groups['oo_nodes_to_config'] | union(groups['oo_masters_to_config']) }}" + +- import_playbook: ../init/version.yml + vars: + l_openshift_version_set_hosts: "oo_masters_to_config:oo_nodes_to_config:!oo_first_master" + l_openshift_version_check_hosts: "oo_masters_to_config:oo_nodes_to_config" - import_playbook: private/scaleup.yml diff --git a/playbooks/openshift-node/scaleup.yml b/playbooks/openshift-node/scaleup.yml index cf13692ae..9cc7263b7 100644 --- a/playbooks/openshift-node/scaleup.yml +++ b/playbooks/openshift-node/scaleup.yml @@ -12,9 +12,27 @@ new_nodes host group to add nodes. when: - g_new_node_hosts | default([]) | length == 0 + - fail: + msg: > + Please run playbooks/openshift-master/scaleup.yml if you need to + scale up both masters and nodes. This playbook is only needed if + you are only adding new nodes and not new masters. + when: + - g_new_node_hosts | default([]) | length > 0 + - g_new_master_hosts | default([]) | length > 0 + +# if g_new_node_hosts is not empty, oo_nodes_to_config will be set to +# g_new_node_hosts via evaluate_groups.yml + +- import_playbook: ../prerequisites.yml + vars: + l_scale_up_hosts: "oo_nodes_to_config" + l_init_fact_hosts: "oo_masters_to_config:oo_etcd_to_config:oo_lb_to_config:oo_nodes_to_config" + l_sanity_check_hosts: "{{ groups['oo_nodes_to_config'] | union(groups['oo_masters_to_config']) }}" -# Need a better way to do the above check for node without -# running evaluate_groups and init/main.yml -- import_playbook: ../init/main.yml +- import_playbook: ../init/version.yml + vars: + l_openshift_version_set_hosts: "oo_nodes_to_config:!oo_first_master" + l_openshift_version_check_hosts: "oo_nodes_to_config" - import_playbook: private/config.yml diff --git a/playbooks/openstack/README.md b/playbooks/openstack/README.md index d361d6278..842bb34de 100644 --- a/playbooks/openstack/README.md +++ b/playbooks/openstack/README.md @@ -30,15 +30,17 @@ version 10) or newer. It must also satisfy these requirements: - look at the [Minimum Hardware Requirements page][hardware-requirements] for production -* The keypair for SSH must be available in openstack -* `keystonerc` file that lets you talk to the openstack services +* The keypair for SSH must be available in OpenStack +* `keystonerc` file that lets you talk to the OpenStack services * NOTE: only Keystone V2 is currently supported +* A host with the supported version of [Ansible][ansible] installed, see the + [Setup section of the openshift-ansible README][openshift-ansible-setup] + for details on the requirements. Optional: * External Neutron network with a floating IP address pool - ## Installation There are four main parts to the installation: @@ -68,12 +70,11 @@ First, you need to select where to run [Ansible][ansible] from (the *Ansible host*). This can be the computer you read this guide on or an OpenStack VM you'll create specifically for this purpose. -We will use -a +This guide will use a [Docker image that has all the dependencies installed][control-host-image] to make things easier. If you don't want to use Docker, take a look at the [Ansible host dependencies][ansible-dependencies] and make sure -they're installed. +they are installed. Your *Ansible host* needs to have the following: @@ -183,13 +184,16 @@ Then run the provision + install playbook -- this will create the OpenStack resources: ```bash -$ ansible-playbook --user openshift -i inventory \ - openshift-ansible/playbooks/openstack/openshift-cluster/provision_install.yaml \ - -e openshift_repos_enable_testing=true +$ ansible-playbook --user openshift \ + -i openshift-ansible/playbooks/openstack/inventory.py \ + -i inventory \ + openshift-ansible/playbooks/openstack/openshift-cluster/provision_install.yml ``` -Note, you may want to use the testing repo for development purposes only. -Normally, `openshift_repos_enable_testing` should not be specified. +In addition to *your* inventory with your OpenShift and OpenStack +configuration, we are also supplying the [dynamic inventory][dynamic] from +`openshift-ansible/inventory`. It's a script that will look at the Nova servers +and other resources that will be created and let Ansible know about them. If you're using multiple inventories, make sure you pass the path to the right one to `-i`. @@ -219,6 +223,7 @@ advanced configuration: [ansible]: https://www.ansible.com/ [openshift-ansible]: https://github.com/openshift/openshift-ansible +[openshift-ansible-setup]: https://github.com/openshift/openshift-ansible#setup [devstack]: https://docs.openstack.org/devstack/ [tripleo]: http://tripleo.org/ [ansible-dependencies]: ./advanced-configuration.md#dependencies-for-localhost-ansible-controladmin-node @@ -233,3 +238,4 @@ advanced configuration: [loadbalancer]: ./advanced-configuration.md#multi-master-configuration [external-dns]: ./advanced-configuration.md#dns-configuration-variables [cinder-registry]: ./advanced-configuration.md#creating-and-using-a-cinder-volume-for-the-openshift-registry +[dynamic]: http://docs.ansible.com/ansible/latest/intro_dynamic_inventory.html diff --git a/playbooks/openstack/advanced-configuration.md b/playbooks/openstack/advanced-configuration.md index 2c9b70b5f..e8f4cfc32 100644 --- a/playbooks/openstack/advanced-configuration.md +++ b/playbooks/openstack/advanced-configuration.md @@ -1,9 +1,8 @@ ## Dependencies for localhost (ansible control/admin node) -* [Ansible 2.3](https://pypi.python.org/pypi/ansible) -* [Ansible-galaxy](https://pypi.python.org/pypi/ansible-galaxy-local-deps) -* [jinja2](http://jinja.pocoo.org/docs/2.9/) -* [shade](https://pypi.python.org/pypi/shade) +* [Ansible](https://pypi.python.org/pypi/ansible) version >=2.4.0 +* [jinja2](http://jinja.pocoo.org/docs/2.9/) version >= 2.10 +* [shade](https://pypi.python.org/pypi/shade) version >= 1.26 * python-jmespath / [jmespath](https://pypi.python.org/pypi/jmespath) * python-dns / [dnspython](https://pypi.python.org/pypi/dnspython) * Become (sudo) is not required. @@ -133,7 +132,7 @@ You can also access the OpenShift cluster with a web browser by going to: https://master-0.openshift.example.com:8443 Note that for this to work, the OpenShift nodes must be accessible -from your computer and it's DNS configuration must use the cruster's +from your computer and its DNS configuration must use the cluster's DNS. @@ -153,7 +152,7 @@ openstack stack delete --wait --yes openshift.example.com Pay special attention to the values in the first paragraph -- these will depend on your OpenStack environment. -Note that the provsisioning playbooks update the original Neutron subnet +Note that the provisioning playbooks update the original Neutron subnet created with the Heat stack to point to the configured DNS servers. So the provisioned cluster nodes will start using those natively as default nameservers. Technically, this allows to deploy OpenShift clusters @@ -162,7 +161,7 @@ without dnsmasq proxies. The `openshift_openstack_clusterid` and `openshift_openstack_public_dns_domain` will form the cluster's public DNS domain all your servers will be under. With the default values, this will be `openshift.example.com`. For workloads, the -default subdomain is 'apps'. That sudomain can be set as well by the +default subdomain is 'apps'. That subdomain can be set as well by the `openshift_openstack_app_subdomain` variable in the inventory. If you want to use a two sets of hostnames for public and private/prefixed DNS @@ -334,7 +333,7 @@ or your trusted network. The most important is the `openshift_openstack_node_ing that restricts public access to the deployed DNS server and cluster nodes' ephemeral ports range. -Note, the command ``curl https://api.ipify.org`` helps fiding an external +Note, the command ``curl https://api.ipify.org`` helps finding an external IP address of your box (the ansible admin node). There is also the `manage_packages` variable (defaults to True) you @@ -372,6 +371,112 @@ In order to set a custom entrypoint, update `openshift_master_cluster_public_hos Note than an empty hostname does not work, so if your domain is `openshift.example.com`, you cannot set this value to simply `openshift.example.com`. + +## Using Cinder-backed Persistent Volumes + +You will need to set up OpenStack credentials. You can try putting this in your +`inventory/group_vars/OSEv3.yml`: + + openshift_cloudprovider_kind: openstack + openshift_cloudprovider_openstack_auth_url: "{{ lookup('env','OS_AUTH_URL') }}" + openshift_cloudprovider_openstack_username: "{{ lookup('env','OS_USERNAME') }}" + openshift_cloudprovider_openstack_password: "{{ lookup('env','OS_PASSWORD') }}" + openshift_cloudprovider_openstack_tenant_name: "{{ lookup('env','OS_PROJECT_NAME') }}" + openshift_cloudprovider_openstack_domain_name: "{{ lookup('env','OS_USER_DOMAIN_NAME') }}" + openshift_cloudprovider_openstack_blockstorage_version: v2 + +**NOTE**: you must specify the Block Storage version as v2, because OpenShift +does not support the v3 API yet and the version detection is currently not +working properly. + +For more information, consult the [Configuring for OpenStack page in the OpenShift documentation][openstack-credentials]. + +[openstack-credentials]: https://docs.openshift.org/latest/install_config/configuring_openstack.html#install-config-configuring-openstack + +**NOTE** the OpenStack integration currently requires DNS to be configured and +running and the `openshift_hostname` variable must match the Nova server name +for each node. The cluster deployment will fail without it. If you use the +provided OpenStack dynamic inventory and configure the +`openshift_openstack_dns_nameservers` Ansible variable, this will be handled +for you. + +After a successful deployment, the cluster is configured for Cinder persistent +volumes. + +### Validation + +1. Log in and create a new project (with `oc login` and `oc new-project`) +2. Create a file called `cinder-claim.yaml` with the following contents: + +```yaml +apiVersion: "v1" +kind: "PersistentVolumeClaim" +metadata: + name: "claim1" +spec: + accessModes: + - "ReadWriteOnce" + resources: + requests: + storage: "1Gi" +``` +3. Run `oc create -f cinder-claim.yaml` to create the Persistent Volume Claim object in OpenShift +4. Run `oc describe pvc claim1` to verify that the claim was created and its Status is `Bound` +5. Run `openstack volume list` + * A new volume called `kubernetes-dynamic-pvc-UUID` should be created + * Its size should be `1` + * It should not be attached to any server +6. Create a file called `mysql-pod.yaml` with the following contents: + +```yaml +apiVersion: v1 +kind: Pod +metadata: + name: mysql + labels: + name: mysql +spec: + containers: + - resources: + limits : + cpu: 0.5 + image: openshift/mysql-55-centos7 + name: mysql + env: + - name: MYSQL_ROOT_PASSWORD + value: yourpassword + - name: MYSQL_USER + value: wp_user + - name: MYSQL_PASSWORD + value: wp_pass + - name: MYSQL_DATABASE + value: wp_db + ports: + - containerPort: 3306 + name: mysql + volumeMounts: + - name: mysql-persistent-storage + mountPath: /var/lib/mysql/data + volumes: + - name: mysql-persistent-storage + persistentVolumeClaim: + claimName: claim1 +``` + +7. Run `oc create -f mysql-pod.yaml` to create the pod +8. Run `oc describe pod mysql` + * Its events should show that the pod has successfully attached the volume above + * It should show no errors + * `openstack volume list` should show the volume attached to an OpenShift app node + * NOTE: this can take several seconds +9. After a while, `oc get pod` should show the `mysql` pod as running +10. Run `oc delete pod mysql` to remove the pod + * The Cinder volume should no longer be attached +11. Run `oc delete pvc claim1` to remove the volume claim + * The Cinder volume should be deleted + + + ## Creating and using a Cinder volume for the OpenShift registry You can optionally have the playbooks create a Cinder volume and set @@ -415,7 +520,7 @@ OpenStack)[openstack] for more information. [openstack]: https://docs.openshift.org/latest/install_config/configuring_openstack.html -Next, we need to instruct OpenShift to use the Cinder volume for it's +Next, we need to instruct OpenShift to use the Cinder volume for its registry. Again in `OSEv3.yml`: #openshift_hosted_registry_storage_kind: openstack @@ -470,12 +575,12 @@ The **Cinder volume ID**, **filesystem** and **volume size** variables must correspond to the values in your volume. The volume ID must be the **UUID** of the Cinder volume, *not its name*. -We can do formate the volume for you if you ask for it in +The volume can also be formatted if you configure it in `inventory/group_vars/all.yml`: openshift_openstack_prepare_and_format_registry_volume: true -**NOTE:** doing so **will destroy any data that's currently on the volume**! +**NOTE:** Formatting **will destroy any data that's currently on the volume**! You can also run the registry setup playbook directly: diff --git a/playbooks/openstack/sample-inventory/inventory.py b/playbooks/openstack/inventory.py index 45cc4e15a..76e658eb7 100755 --- a/playbooks/openstack/sample-inventory/inventory.py +++ b/playbooks/openstack/inventory.py @@ -89,13 +89,15 @@ def build_inventory(): # TODO(shadower): what about multiple networks? if server.private_v4: hostvars['private_v4'] = server.private_v4 + hostvars['openshift_ip'] = server.private_v4 + # NOTE(shadower): Yes, we set both hostname and IP to the private # IP address for each node. OpenStack doesn't resolve nodes by # name at all, so using a hostname here would require an internal # DNS which would complicate the setup and potentially introduce # performance issues. - hostvars['openshift_ip'] = server.private_v4 - hostvars['openshift_hostname'] = server.private_v4 + hostvars['openshift_hostname'] = server.metadata.get( + 'openshift_hostname', server.private_v4) hostvars['openshift_public_hostname'] = server.name if server.metadata['host-type'] == 'cns': diff --git a/playbooks/openstack/openshift-cluster/provision.yml b/playbooks/openstack/openshift-cluster/provision.yml index a38d7bff7..73c1926a0 100644 --- a/playbooks/openstack/openshift-cluster/provision.yml +++ b/playbooks/openstack/openshift-cluster/provision.yml @@ -26,8 +26,8 @@ - name: Gather facts for the new nodes setup: -- name: set common facts - import_playbook: ../../init/facts.yml +- import_playbook: ../../init/basic_facts.yml +- import_playbook: ../../init/cluster_facts.yml # TODO(shadower): consider splitting this up so people can stop here diff --git a/playbooks/openstack/sample-inventory/group_vars/OSEv3.yml b/playbooks/openstack/sample-inventory/group_vars/OSEv3.yml index 481807dc9..1287b25f3 100644 --- a/playbooks/openstack/sample-inventory/group_vars/OSEv3.yml +++ b/playbooks/openstack/sample-inventory/group_vars/OSEv3.yml @@ -20,6 +20,7 @@ openshift_hosted_registry_wait: True #openshift_cloudprovider_openstack_password: "{{ lookup('env','OS_PASSWORD') }}" #openshift_cloudprovider_openstack_tenant_name: "{{ lookup('env','OS_TENANT_NAME') }}" #openshift_cloudprovider_openstack_region: "{{ lookup('env', 'OS_REGION_NAME') }}" +#openshift_cloudprovider_openstack_blockstorage_version: v2 ## Use Cinder volume for Openshift registry: @@ -42,7 +43,7 @@ openshift_hosted_registry_wait: True # NOTE(shadower): the hostname check seems to always fail because the # host's floating IP address doesn't match the address received from # inside the host. -openshift_override_hostname_check: true +openshift_hostname_check: false # For POCs or demo environments that are using smaller instances than # the official recommended values for RAM and DISK, uncomment the line below. diff --git a/playbooks/prerequisites.yml b/playbooks/prerequisites.yml index 7802f83d9..0b76ca862 100644 --- a/playbooks/prerequisites.yml +++ b/playbooks/prerequisites.yml @@ -1,18 +1,21 @@ --- +# l_scale_up_hosts may be passed in via various scaleup plays. + - import_playbook: init/main.yml vars: skip_verison: True + l_install_base_packages: True - import_playbook: init/validate_hostnames.yml when: not (skip_validate_hostnames | default(False)) - import_playbook: init/repos.yml -- import_playbook: init/base_packages.yml - # This is required for container runtime for crio, only needs to run once. - name: Configure os_firewall - hosts: oo_masters_to_config:oo_etcd_to_config:oo_lb_to_config:oo_nfs_to_config:oo_nodes_to_config + hosts: "{{ l_scale_up_hosts | default(l_default_firewall_hosts) }}" + vars: + l_default_firewall_hosts: "oo_masters_to_config:oo_etcd_to_config:oo_lb_to_config:oo_nfs_to_config:oo_nodes_to_config" roles: - role: os_firewall diff --git a/roles/ansible_service_broker/tasks/install.yml b/roles/ansible_service_broker/tasks/install.yml index ba2f7293b..f869b5fae 100644 --- a/roles/ansible_service_broker/tasks/install.yml +++ b/roles/ansible_service_broker/tasks/install.yml @@ -72,6 +72,15 @@ - apiGroups: ["image.openshift.io", ""] resources: ["images"] verbs: ["get", "list"] + - apiGroups: ["network.openshift.io"] + resources: ["clusternetworks", "netnamespaces"] + verbs: ["get"] + - apiGroups: ["network.openshift.io"] + resources: ["netnamespaces"] + verbs: ["update"] + - apiGroups: ["networking.k8s.io"] + resources: ["networkpolicies"] + verbs: ["create", "delete"] - name: Create asb-access cluster role oc_clusterrole: @@ -366,6 +375,11 @@ secret: secretName: etcd-auth-secret +- name: set auth name and type facts if needed + set_fact: + ansible_service_broker_registry_auth_type: "secret" + ansible_service_broker_registry_auth_name: "asb-registry-auth" + when: ansible_service_broker_registry_user != "" and ansible_service_broker_registry_password != "" # TODO: saw a oc_configmap in the library, but didn't understand how to get it to do the following: - name: Create config map for ansible-service-broker @@ -393,6 +407,8 @@ org: {{ ansible_service_broker_registry_organization }} tag: {{ ansible_service_broker_registry_tag }} white_list: {{ ansible_service_broker_registry_whitelist | to_yaml }} + auth_type: "{{ ansible_service_broker_registry_auth_type | default("") }}" + auth_name: "{{ ansible_service_broker_registry_auth_name | default("") }}" - type: local_openshift name: localregistry namespaces: ['openshift'] @@ -438,6 +454,7 @@ data: "{{ ansible_service_broker_registry_user }}" - path: password data: "{{ ansible_service_broker_registry_password }}" + when: ansible_service_broker_registry_user != "" and ansible_service_broker_registry_password != "" - name: Create the Broker resource in the catalog oc_obj: diff --git a/roles/calico_master/tasks/main.yml b/roles/calico_master/tasks/main.yml index 05415a4d6..834ebba64 100644 --- a/roles/calico_master/tasks/main.yml +++ b/roles/calico_master/tasks/main.yml @@ -23,7 +23,7 @@ -f {{ mktemp.stdout }}/calico-policy-controller.yml --config={{ openshift.common.config_base }}/master/admin.kubeconfig register: calico_create_output - failed_when: ('already exists' not in calico_create_output.stderr) and ('created' not in calico_create_output.stdout) + failed_when: "('already exists' not in calico_create_output.stderr) and ('created' not in calico_create_output.stdout) and calico_create_output.rc != 0" changed_when: ('created' in calico_create_output.stdout) - name: Calico Master | Delete temp directory diff --git a/roles/container_runtime/tasks/docker_upgrade_check.yml b/roles/container_runtime/tasks/docker_upgrade_check.yml index 7831f4c7d..8dd916e79 100644 --- a/roles/container_runtime/tasks/docker_upgrade_check.yml +++ b/roles/container_runtime/tasks/docker_upgrade_check.yml @@ -21,6 +21,7 @@ retries: 4 until: curr_docker_version is succeeded changed_when: false + when: not openshift_is_atomic | bool - name: Get latest available version of Docker command: > @@ -29,7 +30,9 @@ retries: 4 until: avail_docker_version is succeeded # Don't expect docker rpm to be available on hosts that don't already have it installed: - when: pkg_check.rc == 0 + when: + - not openshift_is_atomic | bool + - pkg_check.rc == 0 failed_when: false changed_when: false @@ -37,9 +40,10 @@ msg: This playbook requires access to Docker 1.12 or later # Disable the 1.12 requirement if the user set a specific Docker version when: - - docker_version is not defined - - docker_upgrade is not defined or docker_upgrade | bool == True - - (pkg_check.rc == 0 and (avail_docker_version.stdout == "" or avail_docker_version.stdout is version_compare('1.12','<'))) + - not openshift_is_atomic | bool + - docker_version is not defined + - docker_upgrade is not defined or docker_upgrade | bool == True + - (pkg_check.rc == 0 and (avail_docker_version.stdout == "" or avail_docker_version.stdout is version_compare('1.12','<'))) # Default l_docker_upgrade to False, we'll set to True if an upgrade is required: - set_fact: @@ -48,14 +52,17 @@ # Make sure a docker_version is set if none was requested: - set_fact: docker_version: "{{ avail_docker_version.stdout }}" - when: pkg_check.rc == 0 and docker_version is not defined + when: + - not openshift_is_atomic | bool + - pkg_check.rc == 0 and docker_version is not defined - name: Flag for Docker upgrade if necessary set_fact: l_docker_upgrade: True when: - - pkg_check.rc == 0 - - curr_docker_version.stdout is version_compare(docker_version,'<') + - not openshift_is_atomic | bool + - pkg_check.rc == 0 + - curr_docker_version.stdout is version_compare(docker_version,'<') # Additional checks for Atomic hosts: - name: Determine available Docker @@ -70,5 +77,5 @@ - fail: msg: This playbook requires access to Docker 1.12 or later when: - - openshift_is_atomic | bool - - l_docker_version.avail_version | default(l_docker_version.curr_version, true) is version_compare('1.12','<') + - openshift_is_atomic | bool + - l_docker_version.avail_version | default(l_docker_version.curr_version, true) is version_compare('1.12','<') diff --git a/roles/container_runtime/tasks/package_docker.yml b/roles/container_runtime/tasks/package_docker.yml index d6e7e7fed..ed9a2709b 100644 --- a/roles/container_runtime/tasks/package_docker.yml +++ b/roles/container_runtime/tasks/package_docker.yml @@ -1,6 +1,17 @@ --- - include_tasks: common/pre.yml +# In some cases, some services may be run as containers and docker may still +# be installed via rpm. +- include_tasks: common/atomic_proxy.yml + when: + - > + (openshift_use_system_containers | default(False)) | bool + or (openshift_use_etcd_system_container | default(False)) | bool + or (openshift_use_openvswitch_system_container | default(False)) | bool + or (openshift_use_node_system_container | default(False)) | bool + or (openshift_use_master_system_container | default(False)) | bool + - name: Get current installed Docker version command: "{{ repoquery_installed }} --qf '%{version}' docker" when: not openshift_is_atomic | bool diff --git a/roles/etcd/tasks/auxiliary/drop_etcdctl.yml b/roles/etcd/tasks/auxiliary/drop_etcdctl.yml index 881a8c270..cab835e20 100644 --- a/roles/etcd/tasks/auxiliary/drop_etcdctl.yml +++ b/roles/etcd/tasks/auxiliary/drop_etcdctl.yml @@ -1,7 +1,7 @@ --- - name: Install etcd for etcdctl package: name=etcd{{ '-' + etcd_version if etcd_version is defined else '' }} state=present - when: not openshift_is_atomic | bool + when: not openshift_is_containerized | bool register: result until: result is succeeded diff --git a/roles/etcd/tasks/certificates/fetch_client_certificates_from_ca.yml b/roles/etcd/tasks/certificates/fetch_client_certificates_from_ca.yml index 78578a055..ce295d2f5 100644 --- a/roles/etcd/tasks/certificates/fetch_client_certificates_from_ca.yml +++ b/roles/etcd/tasks/certificates/fetch_client_certificates_from_ca.yml @@ -57,6 +57,7 @@ # Certificates must be signed serially in order to avoid competing # for the serial file. +# delegated_serial_command is a custom module in lib_utils - name: Sign and create the client crt delegated_serial_command: command: > diff --git a/roles/etcd/tasks/certificates/fetch_server_certificates_from_ca.yml b/roles/etcd/tasks/certificates/fetch_server_certificates_from_ca.yml index 987380d0c..7c8b87d99 100644 --- a/roles/etcd/tasks/certificates/fetch_server_certificates_from_ca.yml +++ b/roles/etcd/tasks/certificates/fetch_server_certificates_from_ca.yml @@ -50,6 +50,7 @@ # Certificates must be signed serially in order to avoid competing # for the serial file. +# delegated_serial_command is a custom module in lib_utils - name: Sign and create the server crt delegated_serial_command: command: > @@ -83,6 +84,7 @@ # Certificates must be signed serially in order to avoid competing # for the serial file. +# delegated_serial_command is a custom module in lib_utils - name: Sign and create the peer crt delegated_serial_command: command: > diff --git a/roles/kuryr/tasks/node.yaml b/roles/kuryr/tasks/node.yaml index 08f2d5adc..41d0ead20 100644 --- a/roles/kuryr/tasks/node.yaml +++ b/roles/kuryr/tasks/node.yaml @@ -40,7 +40,7 @@ regexp: '^OPTIONS="?(.*?)"?$' backrefs: yes backup: yes - line: 'OPTIONS="\1 --disable dns,proxy,plugins"' + line: 'OPTIONS="\1 --disable proxy"' - name: force node restart to disable the proxy service: diff --git a/roles/kuryr/templates/cni-daemonset.yaml.j2 b/roles/kuryr/templates/cni-daemonset.yaml.j2 index 39348ae90..09f4c7dfe 100644 --- a/roles/kuryr/templates/cni-daemonset.yaml.j2 +++ b/roles/kuryr/templates/cni-daemonset.yaml.j2 @@ -26,6 +26,13 @@ spec: image: kuryr/cni:latest imagePullPolicy: IfNotPresent command: [ "cni_ds_init" ] + env: + - name: CNI_DAEMON + value: "True" + - name: KUBERNETES_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName securityContext: privileged: true volumeMounts: @@ -38,6 +45,10 @@ spec: subPath: kuryr-cni.conf - name: etc mountPath: /etc + - name: proc + mountPath: /host_proc + - name: openvswitch + mountPath: /var/run/openvswitch volumes: - name: bin hostPath: @@ -50,4 +61,10 @@ spec: name: kuryr-config - name: etc hostPath: - path: /etc
\ No newline at end of file + path: /etc + - name: proc + hostPath: + path: /proc + - name: openvswitch + hostPath: + path: /var/run/openvswitch diff --git a/roles/kuryr/templates/configmap.yaml.j2 b/roles/kuryr/templates/configmap.yaml.j2 index 96c215f00..4bf1dbddf 100644 --- a/roles/kuryr/templates/configmap.yaml.j2 +++ b/roles/kuryr/templates/configmap.yaml.j2 @@ -16,17 +16,17 @@ data: # Directory for Kuryr vif binding executables. (string value) #bindir = /usr/libexec/kuryr + # Neutron subnetpool name will be prefixed by this. (string value) + #subnetpool_name_prefix = kuryrPool + + # baremetal or nested-containers are the supported values. (string value) + #deployment_type = baremetal + # If set to true, the logging level will be set to DEBUG instead of the default # INFO level. (boolean value) # Note: This option can be changed without restarting. #debug = false - # DEPRECATED: If set to false, the logging level will be set to WARNING instead - # of the default INFO level. (boolean value) - # This option is deprecated for removal. - # Its value may be silently ignored in the future. - #verbose = true - # The name of a logging configuration file. This file is appended to any # existing logging configuration files. For details about logging configuration # files, see the Python logging module documentation. Note that when logging @@ -46,7 +46,7 @@ data: # logging will go to stderr as defined by use_stderr. This option is ignored if # log_config_append is set. (string value) # Deprecated group/name - [DEFAULT]/logfile - #log_file = /var/log/kuryr/kuryr-controller.log + #log_file = <None> # (Optional) The base directory used for relative log_file paths. This option # is ignored if log_config_append is set. (string value) @@ -65,13 +65,19 @@ data: # is set. (boolean value) #use_syslog = false + # Enable journald for logging. If running in a systemd environment you may wish + # to enable journal support. Doing so will use the journal native protocol + # which includes structured metadata in addition to log messages.This option is + # ignored if log_config_append is set. (boolean value) + #use_journal = false + # Syslog facility to receive log lines. This option is ignored if # log_config_append is set. (string value) #syslog_log_facility = LOG_USER # Log output to standard error. This option is ignored if log_config_append is # set. (boolean value) - #use_stderr = true + #use_stderr = false # Format string to use for log messages with context. (string value) #logging_context_format_string = %(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [%(request_id)s %(user_identity)s] %(instance)s%(message)s @@ -93,7 +99,7 @@ data: # List of package logging levels in logger=LEVEL pairs. This option is ignored # if log_config_append is set. (list value) - #default_log_levels = amqp=WARN,amqplib=WARN,boto=WARN,qpid=WARN,sqlalchemy=WARN,suds=INFO,oslo.messaging=INFO,iso8601=WARN,requests.packages.urllib3.connectionpool=WARN,urllib3.connectionpool=WARN,websocket=WARN,requests.packages.urllib3.util.retry=WARN,urllib3.util.retry=WARN,keystonemiddleware=WARN,routes.middleware=WARN,stevedore=WARN,taskflow=WARN,keystoneauth=WARN,oslo.cache=INFO,dogpile.core.dogpile=INFO + #default_log_levels = amqp=WARN,amqplib=WARN,boto=WARN,qpid=WARN,sqlalchemy=WARN,suds=INFO,oslo.messaging=INFO,oslo_messaging=INFO,iso8601=WARN,requests.packages.urllib3.connectionpool=WARN,urllib3.connectionpool=WARN,websocket=WARN,requests.packages.urllib3.util.retry=WARN,urllib3.util.retry=WARN,keystonemiddleware=WARN,routes.middleware=WARN,stevedore=WARN,taskflow=WARN,keystoneauth=WARN,oslo.cache=INFO,dogpile.core.dogpile=INFO # Enables or disables publication of error events. (boolean value) #publish_errors = false @@ -106,15 +112,86 @@ data: # value) #instance_uuid_format = "[instance: %(uuid)s] " + # Interval, number of seconds, of log rate limiting. (integer value) + #rate_limit_interval = 0 + + # Maximum number of logged messages per rate_limit_interval. (integer value) + #rate_limit_burst = 0 + + # Log level name used by rate limiting: CRITICAL, ERROR, INFO, WARNING, DEBUG + # or empty string. Logs with level greater or equal to rate_limit_except_level + # are not filtered. An empty string means that all levels are filtered. (string + # value) + #rate_limit_except_level = CRITICAL + # Enables or disables fatal status of deprecations. (boolean value) #fatal_deprecations = false [binding] + # Configuration options for container interface binding. - driver = kuryr.lib.binding.drivers.vlan + # + # From kuryr_kubernetes + # + + # The name prefix of the veth endpoint put inside the container. (string value) + #veth_dst_prefix = eth + + # Driver to use for binding and unbinding ports. (string value) + # Deprecated group/name - [binding]/driver + #default_driver = kuryr.lib.binding.drivers.veth + + # Drivers to use for binding and unbinding ports. (list value) + #enabled_drivers = kuryr.lib.binding.drivers.veth + + # Specifies the name of the Nova instance interface to link the virtual devices + # to (only applicable to some binding drivers. (string value) link_iface = eth0 + driver = kuryr.lib.binding.drivers.vlan + + + [cni_daemon] + + # + # From kuryr_kubernetes + # + + # Enable CNI Daemon configuration. (boolean value) + daemon_enabled = true + + # Bind address for CNI daemon HTTP server. It is recommened to allow only local + # connections. (string value) + bind_address = 127.0.0.1:50036 + + # Maximum number of processes that will be spawned to process requests from CNI + # driver. (integer value) + #worker_num = 30 + + # Time (in seconds) the CNI daemon will wait for VIF annotation to appear in + # pod metadata before failing the CNI request. (integer value) + #vif_annotation_timeout = 120 + + # Kuryr uses pyroute2 library to manipulate networking interfaces. When + # processing a high number of Kuryr requests in parallel, it may take kernel + # more time to process all networking stack changes. This option allows to tune + # internal pyroute2 timeout. (integer value) + #pyroute2_timeout = 30 + + # Set to True when you are running kuryr-daemon inside a Docker container on + # Kubernetes host. E.g. as DaemonSet on Kubernetes cluster Kuryr is supposed to + # provide networking for. This mainly means thatkuryr-daemon will look for + # network namespaces in $netns_proc_dir instead of /proc. (boolean value) + docker_mode = true + + # When docker_mode is set to True, this config option should be set to where + # host's /proc directory is mounted. Please note that mounting it is necessary + # to allow Kuryr-Kubernetes to move host interfaces between host network + # namespaces, which is essential for Kuryr to work. (string value) + netns_proc_dir = /host_proc + + [kubernetes] # @@ -164,11 +241,6 @@ data: # The driver that manages VIFs pools for Kubernetes Pods (string value) vif_pool_driver = {{ kuryr_openstack_enable_pools | default(False) | ternary('nested', 'noop') }} - [vif_pool] - ports_pool_max = {{ kuryr_openstack_pool_max | default(0) }} - ports_pool_min = {{ kuryr_openstack_pool_min | default(1) }} - ports_pool_batch = {{ kuryr_openstack_pool_batch | default(5) }} - ports_pool_update_frequency = {{ kuryr_openstack_pool_update_frequency | default(20) }} [neutron] # Configuration options for OpenStack Neutron @@ -232,13 +304,55 @@ data: external_svc_subnet = {{ kuryr_openstack_external_svc_subnet_id }} [pod_vif_nested] + worker_nodes_subnet = {{ kuryr_openstack_worker_nodes_subnet_id }} + + + [pool_manager] + + # + # From kuryr_kubernetes + # + + # Absolute path to socket file that will be used for communication with the + # Pool Manager daemon (string value) + #sock_file = /run/kuryr/kuryr_manage.sock + + + [vif_pool] + + # + # From kuryr_kubernetes + # + + # Set a maximun amount of ports per pool. 0 to disable (integer value) + ports_pool_max = {{ kuryr_openstack_pool_max | default(0) }} + + # Set a target minimum size of the pool of ports (integer value) + ports_pool_min = {{ kuryr_openstack_pool_min | default(1) }} + + # Number of ports to be created in a bulk request (integer value) + ports_pool_batch = {{ kuryr_openstack_pool_batch | default(5) }} + + # Minimun interval (in seconds) between pool updates (integer value) + ports_pool_update_frequency = {{ kuryr_openstack_pool_update_frequency | default(20) }} + kuryr-cni.conf: |+ [DEFAULT] # # From kuryr_kubernetes # + + # Directory for Kuryr vif binding executables. (string value) + #bindir = /usr/libexec/kuryr + + # Neutron subnetpool name will be prefixed by this. (string value) + #subnetpool_name_prefix = kuryrPool + + # baremetal or nested-containers are the supported values. (string value) + #deployment_type = baremetal + # If set to true, the logging level will be set to DEBUG instead of the default # INFO level. (boolean value) # Note: This option can be changed without restarting. @@ -263,7 +377,7 @@ data: # logging will go to stderr as defined by use_stderr. This option is ignored if # log_config_append is set. (string value) # Deprecated group/name - [DEFAULT]/logfile - #log_file = /var/log/kuryr/cni.log + #log_file = <None> # (Optional) The base directory used for relative log_file paths. This option # is ignored if log_config_append is set. (string value) @@ -282,6 +396,12 @@ data: # is set. (boolean value) #use_syslog = false + # Enable journald for logging. If running in a systemd environment you may wish + # to enable journal support. Doing so will use the journal native protocol + # which includes structured metadata in addition to log messages.This option is + # ignored if log_config_append is set. (boolean value) + #use_journal = false + # Syslog facility to receive log lines. This option is ignored if # log_config_append is set. (string value) #syslog_log_facility = LOG_USER @@ -310,7 +430,7 @@ data: # List of package logging levels in logger=LEVEL pairs. This option is ignored # if log_config_append is set. (list value) - #default_log_levels = amqp=WARN,amqplib=WARN,boto=WARN,qpid=WARN,sqlalchemy=WARN,suds=INFO,oslo.messaging=INFO,iso8601=WARN,requests.packages.urllib3.connectionpool=WARN,urllib3.connectionpool=WARN,websocket=WARN,requests.packages.urllib3.util.retry=WARN,urllib3.util.retry=WARN,keystonemiddleware=WARN,routes.middleware=WARN,stevedore=WARN,taskflow=WARN,keystoneauth=WARN,oslo.cache=INFO,dogpile.core.dogpile=INFO + #default_log_levels = amqp=WARN,amqplib=WARN,boto=WARN,qpid=WARN,sqlalchemy=WARN,suds=INFO,oslo.messaging=INFO,oslo_messaging=INFO,iso8601=WARN,requests.packages.urllib3.connectionpool=WARN,urllib3.connectionpool=WARN,websocket=WARN,requests.packages.urllib3.util.retry=WARN,urllib3.util.retry=WARN,keystonemiddleware=WARN,routes.middleware=WARN,stevedore=WARN,taskflow=WARN,keystoneauth=WARN,oslo.cache=INFO,dogpile.core.dogpile=INFO # Enables or disables publication of error events. (boolean value) #publish_errors = false @@ -323,14 +443,85 @@ data: # value) #instance_uuid_format = "[instance: %(uuid)s] " + # Interval, number of seconds, of log rate limiting. (integer value) + #rate_limit_interval = 0 + + # Maximum number of logged messages per rate_limit_interval. (integer value) + #rate_limit_burst = 0 + + # Log level name used by rate limiting: CRITICAL, ERROR, INFO, WARNING, DEBUG + # or empty string. Logs with level greater or equal to rate_limit_except_level + # are not filtered. An empty string means that all levels are filtered. (string + # value) + #rate_limit_except_level = CRITICAL + # Enables or disables fatal status of deprecations. (boolean value) #fatal_deprecations = false [binding] + # Configuration options for container interface binding. + + # + # From kuryr_kubernetes + # + + # The name prefix of the veth endpoint put inside the container. (string value) + #veth_dst_prefix = eth + + # Driver to use for binding and unbinding ports. (string value) + # Deprecated group/name - [binding]/driver + #default_driver = kuryr.lib.binding.drivers.veth + + # Drivers to use for binding and unbinding ports. (list value) + #enabled_drivers = kuryr.lib.binding.drivers.veth + + # Specifies the name of the Nova instance interface to link the virtual devices + # to (only applicable to some binding drivers. (string value) + link_iface = eth0 driver = kuryr.lib.binding.drivers.vlan - link_iface = {{ kuryr_cni_link_interface }} + + + [cni_daemon] + + # + # From kuryr_kubernetes + # + + # Enable CNI Daemon configuration. (boolean value) + daemon_enabled = true + + # Bind address for CNI daemon HTTP server. It is recommened to allow only local + # connections. (string value) + bind_address = 127.0.0.1:50036 + + # Maximum number of processes that will be spawned to process requests from CNI + # driver. (integer value) + #worker_num = 30 + + # Time (in seconds) the CNI daemon will wait for VIF annotation to appear in + # pod metadata before failing the CNI request. (integer value) + #vif_annotation_timeout = 120 + + # Kuryr uses pyroute2 library to manipulate networking interfaces. When + # processing a high number of Kuryr requests in parallel, it may take kernel + # more time to process all networking stack changes. This option allows to tune + # internal pyroute2 timeout. (integer value) + #pyroute2_timeout = 30 + + # Set to True when you are running kuryr-daemon inside a Docker container on + # Kubernetes host. E.g. as DaemonSet on Kubernetes cluster Kuryr is supposed to + # provide networking for. This mainly means thatkuryr-daemon will look for + # network namespaces in $netns_proc_dir instead of /proc. (boolean value) + docker_mode = true + + # When docker_mode is set to True, this config option should be set to where + # host's /proc directory is mounted. Please note that mounting it is necessary + # to allow Kuryr-Kubernetes to move host interfaces between host network + # namespaces, which is essential for Kuryr to work. (string value) + netns_proc_dir = /host_proc + [kubernetes] @@ -341,12 +532,136 @@ data: # The root URL of the Kubernetes API (string value) api_root = {{ openshift.master.api_url }} - # The token to talk to the k8s API - token_file = /etc/kuryr/token + # Absolute path to client cert to connect to HTTPS K8S_API (string value) + # ssl_client_crt_file = /etc/kuryr/controller.crt + + # Absolute path client key file to connect to HTTPS K8S_API (string value) + # ssl_client_key_file = /etc/kuryr/controller.key # Absolute path to ca cert file to connect to HTTPS K8S_API (string value) - ssl_ca_crt_file = /etc/kuryr/ca.crt + ssl_ca_crt_file = /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + + # The token to talk to the k8s API + token_file = /var/run/secrets/kubernetes.io/serviceaccount/token # HTTPS K8S_API server identity verification (boolean value) # TODO (apuimedo): Make configurable ssl_verify_server_crt = True + + # The driver to determine OpenStack project for pod ports (string value) + pod_project_driver = default + + # The driver to determine OpenStack project for services (string value) + service_project_driver = default + + # The driver to determine Neutron subnets for pod ports (string value) + pod_subnets_driver = default + + # The driver to determine Neutron subnets for services (string value) + service_subnets_driver = default + + # The driver to determine Neutron security groups for pods (string value) + pod_security_groups_driver = default + + # The driver to determine Neutron security groups for services (string value) + service_security_groups_driver = default + + # The driver that provides VIFs for Kubernetes Pods. (string value) + pod_vif_driver = nested-vlan + + # The driver that manages VIFs pools for Kubernetes Pods (string value) + vif_pool_driver = {{ kuryr_openstack_enable_pools | default(False) | ternary('nested', 'noop') }} + + [neutron] + # Configuration options for OpenStack Neutron + + # + # From kuryr_kubernetes + # + + # Authentication URL (string value) + auth_url = {{ kuryr_openstack_auth_url }} + + # Authentication type to load (string value) + # Deprecated group/name - [neutron]/auth_plugin + auth_type = password + + # Domain ID to scope to (string value) + user_domain_name = {{ kuryr_openstack_user_domain_name }} + + # User's password (string value) + password = {{ kuryr_openstack_password }} + + # Domain name containing project (string value) + project_domain_name = {{ kuryr_openstack_project_domain_name }} + + # Project ID to scope to (string value) + # Deprecated group/name - [neutron]/tenant-id + project_id = {{ kuryr_openstack_project_id }} + + # Token (string value) + #token = <None> + + # Trust ID (string value) + #trust_id = <None> + + # User's domain id (string value) + #user_domain_id = <None> + + # User id (string value) + #user_id = <None> + + # Username (string value) + # Deprecated group/name - [neutron]/user-name + username = {{kuryr_openstack_username }} + + # Whether a plugging operation is failed if the port to plug does not become + # active (boolean value) + #vif_plugging_is_fatal = false + + # Seconds to wait for port to become active (integer value) + #vif_plugging_timeout = 0 + + [neutron_defaults] + + pod_security_groups = {{ kuryr_openstack_pod_sg_id }} + pod_subnet = {{ kuryr_openstack_pod_subnet_id }} + service_subnet = {{ kuryr_openstack_service_subnet_id }} + project = {{ kuryr_openstack_pod_project_id }} + # TODO (apuimedo): Remove the duplicated line just after this one once the + # RDO packaging contains the upstream patch + worker_nodes_subnet = {{ kuryr_openstack_worker_nodes_subnet_id }} + + [pod_vif_nested] + + worker_nodes_subnet = {{ kuryr_openstack_worker_nodes_subnet_id }} + + + [pool_manager] + + # + # From kuryr_kubernetes + # + + # Absolute path to socket file that will be used for communication with the + # Pool Manager daemon (string value) + #sock_file = /run/kuryr/kuryr_manage.sock + + + [vif_pool] + + # + # From kuryr_kubernetes + # + + # Set a maximun amount of ports per pool. 0 to disable (integer value) + ports_pool_max = {{ kuryr_openstack_pool_max | default(0) }} + + # Set a target minimum size of the pool of ports (integer value) + ports_pool_min = {{ kuryr_openstack_pool_min | default(1) }} + + # Number of ports to be created in a bulk request (integer value) + ports_pool_batch = {{ kuryr_openstack_pool_batch | default(5) }} + + # Minimun interval (in seconds) between pool updates (integer value) + ports_pool_update_frequency = {{ kuryr_openstack_pool_update_frequency | default(20) }} diff --git a/roles/openshift_persistent_volumes/action_plugins/generate_pv_pvcs_list.py b/roles/lib_utils/action_plugins/generate_pv_pvcs_list.py index eb13a58ba..eb13a58ba 100644 --- a/roles/openshift_persistent_volumes/action_plugins/generate_pv_pvcs_list.py +++ b/roles/lib_utils/action_plugins/generate_pv_pvcs_list.py diff --git a/roles/openshift_certificate_expiry/filter_plugins/oo_cert_expiry.py b/roles/lib_utils/filter_plugins/oo_cert_expiry.py index 58b228fee..58b228fee 100644 --- a/roles/openshift_certificate_expiry/filter_plugins/oo_cert_expiry.py +++ b/roles/lib_utils/filter_plugins/oo_cert_expiry.py diff --git a/roles/lib_utils/filter_plugins/oo_filters.py b/roles/lib_utils/filter_plugins/oo_filters.py index a2ea287cf..ef996fefe 100644 --- a/roles/lib_utils/filter_plugins/oo_filters.py +++ b/roles/lib_utils/filter_plugins/oo_filters.py @@ -4,6 +4,7 @@ """ Custom filters for use in openshift-ansible """ +import json import os import pdb import random @@ -21,13 +22,10 @@ import yaml from ansible import errors from ansible.parsing.yaml.dumper import AnsibleDumper -# ansible.compat.six goes away with Ansible 2.4 -try: - from ansible.compat.six import string_types, u - from ansible.compat.six.moves.urllib.parse import urlparse -except ImportError: - from ansible.module_utils.six import string_types, u - from ansible.module_utils.six.moves.urllib.parse import urlparse +# pylint: disable=import-error,no-name-in-module +from ansible.module_utils.six import string_types, u +# pylint: disable=import-error,no-name-in-module +from ansible.module_utils.six.moves.urllib.parse import urlparse HAS_OPENSSL = False try: @@ -589,6 +587,26 @@ that result to this filter plugin. return secret_name +def lib_utils_oo_l_of_d_to_csv(input_list): + """Map a list of dictionaries, input_list, into a csv string + of json values. + + Example input: + [{'var1': 'val1', 'var2': 'val2'}, {'var1': 'val3', 'var2': 'val4'}] + Example output: + u'{"var1": "val1", "var2": "val2"},{"var1": "val3", "var2": "val4"}' + """ + return ','.join(json.dumps(x) for x in input_list) + + +def map_from_pairs(source, delim="="): + ''' Returns a dict given the source and delim delimited ''' + if source == '': + return dict() + + return dict(item.split(delim) for item in source.split(",")) + + class FilterModule(object): """ Custom ansible filter mapping """ @@ -618,4 +636,6 @@ class FilterModule(object): "lib_utils_oo_contains_rule": lib_utils_oo_contains_rule, "lib_utils_oo_selector_to_string_list": lib_utils_oo_selector_to_string_list, "lib_utils_oo_filter_sa_secrets": lib_utils_oo_filter_sa_secrets, + "lib_utils_oo_l_of_d_to_csv": lib_utils_oo_l_of_d_to_csv, + "map_from_pairs": map_from_pairs } diff --git a/roles/openshift_aws/filter_plugins/openshift_aws_filters.py b/roles/lib_utils/filter_plugins/openshift_aws_filters.py index dfcb11da3..dfcb11da3 100644 --- a/roles/openshift_aws/filter_plugins/openshift_aws_filters.py +++ b/roles/lib_utils/filter_plugins/openshift_aws_filters.py diff --git a/roles/openshift_hosted/filter_plugins/openshift_hosted_filters.py b/roles/lib_utils/filter_plugins/openshift_hosted_filters.py index 003ce5f9e..003ce5f9e 100644 --- a/roles/openshift_hosted/filter_plugins/openshift_hosted_filters.py +++ b/roles/lib_utils/filter_plugins/openshift_hosted_filters.py diff --git a/roles/openshift_master_facts/filter_plugins/openshift_master.py b/roles/lib_utils/filter_plugins/openshift_master.py index ff15f693b..e67b19c28 100644 --- a/roles/openshift_master_facts/filter_plugins/openshift_master.py +++ b/roles/lib_utils/filter_plugins/openshift_master.py @@ -10,11 +10,7 @@ from ansible import errors from ansible.parsing.yaml.dumper import AnsibleDumper from ansible.plugins.filter.core import to_bool as ansible_bool -# ansible.compat.six goes away with Ansible 2.4 -try: - from ansible.compat.six import string_types, u -except ImportError: - from ansible.module_utils.six import string_types, u +from ansible.module_utils.six import string_types, u import yaml diff --git a/roles/etcd/library/delegated_serial_command.py b/roles/lib_utils/library/delegated_serial_command.py index 0cab1ca88..0cab1ca88 100755 --- a/roles/etcd/library/delegated_serial_command.py +++ b/roles/lib_utils/library/delegated_serial_command.py diff --git a/roles/openshift_certificate_expiry/library/openshift_cert_expiry.py b/roles/lib_utils/library/openshift_cert_expiry.py index e355266b0..e355266b0 100644 --- a/roles/openshift_certificate_expiry/library/openshift_cert_expiry.py +++ b/roles/lib_utils/library/openshift_cert_expiry.py diff --git a/roles/openshift_cli/library/openshift_container_binary_sync.py b/roles/lib_utils/library/openshift_container_binary_sync.py index 440b8ec28..440b8ec28 100644 --- a/roles/openshift_cli/library/openshift_container_binary_sync.py +++ b/roles/lib_utils/library/openshift_container_binary_sync.py diff --git a/roles/lib_utils/lookup_plugins/openshift_master_facts_default_predicates.py b/roles/lib_utils/lookup_plugins/openshift_master_facts_default_predicates.py new file mode 100644 index 000000000..4858c5ec6 --- /dev/null +++ b/roles/lib_utils/lookup_plugins/openshift_master_facts_default_predicates.py @@ -0,0 +1,143 @@ +# pylint: disable=missing-docstring + +import re +from ansible.errors import AnsibleError +from ansible.plugins.lookup import LookupBase + + +class LookupModule(LookupBase): + # pylint: disable=too-many-branches,too-many-statements,too-many-arguments + + def run(self, terms, variables=None, regions_enabled=True, short_version=None, + deployment_type=None, **kwargs): + + predicates = [] + + if short_version is None or deployment_type is None: + if 'openshift' not in variables: + raise AnsibleError("This lookup module requires openshift_facts to be run prior to use") + + if deployment_type is None: + if 'common' not in variables['openshift'] or 'deployment_type' not in variables['openshift']['common']: + raise AnsibleError("This lookup module requires that the deployment_type be set") + + deployment_type = variables['openshift']['common']['deployment_type'] + + if short_version is None: + if 'short_version' in variables['openshift']['common']: + short_version = variables['openshift']['common']['short_version'] + elif 'openshift_release' in variables: + release = variables['openshift_release'] + if release.startswith('v'): + short_version = release[1:] + else: + short_version = release + short_version = '.'.join(short_version.split('.')[0:2]) + elif 'openshift_version' in variables: + version = variables['openshift_version'] + short_version = '.'.join(version.split('.')[0:2]) + else: + # pylint: disable=line-too-long + raise AnsibleError("Either OpenShift needs to be installed or openshift_release needs to be specified") + if deployment_type == 'origin': + if short_version not in ['1.1', '1.2', '1.3', '1.4', '1.5', '3.6', '3.7', '3.8', '3.9', 'latest']: + raise AnsibleError("Unknown short_version %s" % short_version) + elif deployment_type == 'openshift-enterprise': + if short_version not in ['3.1', '3.2', '3.3', '3.4', '3.5', '3.6', '3.7', '3.8', '3.9', 'latest']: + raise AnsibleError("Unknown short_version %s" % short_version) + else: + raise AnsibleError("Unknown deployment_type %s" % deployment_type) + + if deployment_type == 'origin': + # convert short_version to enterprise short_version + short_version = re.sub('^1.', '3.', short_version) + + if short_version == 'latest': + short_version = '3.9' + + # Predicates ordered according to OpenShift Origin source: + # origin/vendor/k8s.io/kubernetes/plugin/pkg/scheduler/algorithmprovider/defaults/defaults.go + + if short_version == '3.1': + predicates.extend([ + {'name': 'PodFitsHostPorts'}, + {'name': 'PodFitsResources'}, + {'name': 'NoDiskConflict'}, + {'name': 'MatchNodeSelector'}, + ]) + + if short_version == '3.2': + predicates.extend([ + {'name': 'PodFitsHostPorts'}, + {'name': 'PodFitsResources'}, + {'name': 'NoDiskConflict'}, + {'name': 'NoVolumeZoneConflict'}, + {'name': 'MatchNodeSelector'}, + {'name': 'MaxEBSVolumeCount'}, + {'name': 'MaxGCEPDVolumeCount'} + ]) + + if short_version == '3.3': + predicates.extend([ + {'name': 'NoDiskConflict'}, + {'name': 'NoVolumeZoneConflict'}, + {'name': 'MaxEBSVolumeCount'}, + {'name': 'MaxGCEPDVolumeCount'}, + {'name': 'GeneralPredicates'}, + {'name': 'PodToleratesNodeTaints'}, + {'name': 'CheckNodeMemoryPressure'} + ]) + + if short_version == '3.4': + predicates.extend([ + {'name': 'NoDiskConflict'}, + {'name': 'NoVolumeZoneConflict'}, + {'name': 'MaxEBSVolumeCount'}, + {'name': 'MaxGCEPDVolumeCount'}, + {'name': 'GeneralPredicates'}, + {'name': 'PodToleratesNodeTaints'}, + {'name': 'CheckNodeMemoryPressure'}, + {'name': 'CheckNodeDiskPressure'}, + {'name': 'MatchInterPodAffinity'} + ]) + + if short_version in ['3.5', '3.6']: + predicates.extend([ + {'name': 'NoVolumeZoneConflict'}, + {'name': 'MaxEBSVolumeCount'}, + {'name': 'MaxGCEPDVolumeCount'}, + {'name': 'MatchInterPodAffinity'}, + {'name': 'NoDiskConflict'}, + {'name': 'GeneralPredicates'}, + {'name': 'PodToleratesNodeTaints'}, + {'name': 'CheckNodeMemoryPressure'}, + {'name': 'CheckNodeDiskPressure'}, + ]) + + if short_version in ['3.7', '3.8', '3.9']: + predicates.extend([ + {'name': 'NoVolumeZoneConflict'}, + {'name': 'MaxEBSVolumeCount'}, + {'name': 'MaxGCEPDVolumeCount'}, + {'name': 'MaxAzureDiskVolumeCount'}, + {'name': 'MatchInterPodAffinity'}, + {'name': 'NoDiskConflict'}, + {'name': 'GeneralPredicates'}, + {'name': 'PodToleratesNodeTaints'}, + {'name': 'CheckNodeMemoryPressure'}, + {'name': 'CheckNodeDiskPressure'}, + {'name': 'NoVolumeNodeConflict'}, + ]) + + if regions_enabled: + region_predicate = { + 'name': 'Region', + 'argument': { + 'serviceAffinity': { + 'labels': ['region'] + } + } + } + predicates.append(region_predicate) + + return predicates diff --git a/roles/lib_utils/lookup_plugins/openshift_master_facts_default_priorities.py b/roles/lib_utils/lookup_plugins/openshift_master_facts_default_priorities.py new file mode 100644 index 000000000..18e1b2e0c --- /dev/null +++ b/roles/lib_utils/lookup_plugins/openshift_master_facts_default_priorities.py @@ -0,0 +1,117 @@ +# pylint: disable=missing-docstring + +import re +from ansible.errors import AnsibleError +from ansible.plugins.lookup import LookupBase + + +class LookupModule(LookupBase): + # pylint: disable=too-many-branches,too-many-statements,too-many-arguments + + def run(self, terms, variables=None, zones_enabled=True, short_version=None, + deployment_type=None, **kwargs): + + priorities = [] + + if short_version is None or deployment_type is None: + if 'openshift' not in variables: + raise AnsibleError("This lookup module requires openshift_facts to be run prior to use") + + if deployment_type is None: + if 'common' not in variables['openshift'] or 'deployment_type' not in variables['openshift']['common']: + raise AnsibleError("This lookup module requires that the deployment_type be set") + + deployment_type = variables['openshift']['common']['deployment_type'] + + if short_version is None: + if 'short_version' in variables['openshift']['common']: + short_version = variables['openshift']['common']['short_version'] + elif 'openshift_release' in variables: + release = variables['openshift_release'] + if release.startswith('v'): + short_version = release[1:] + else: + short_version = release + short_version = '.'.join(short_version.split('.')[0:2]) + elif 'openshift_version' in variables: + version = variables['openshift_version'] + short_version = '.'.join(version.split('.')[0:2]) + else: + # pylint: disable=line-too-long + raise AnsibleError("Either OpenShift needs to be installed or openshift_release needs to be specified") + + if deployment_type == 'origin': + if short_version not in ['1.1', '1.2', '1.3', '1.4', '1.5', '3.6', '3.7', '3.8', '3.9', 'latest']: + raise AnsibleError("Unknown short_version %s" % short_version) + elif deployment_type == 'openshift-enterprise': + if short_version not in ['3.1', '3.2', '3.3', '3.4', '3.5', '3.6', '3.7', '3.8', '3.9', 'latest']: + raise AnsibleError("Unknown short_version %s" % short_version) + else: + raise AnsibleError("Unknown deployment_type %s" % deployment_type) + + if deployment_type == 'origin': + # convert short_version to origin short_version + short_version = re.sub('^1.', '3.', short_version) + + if short_version == 'latest': + short_version = '3.9' + + if short_version == '3.1': + priorities.extend([ + {'name': 'LeastRequestedPriority', 'weight': 1}, + {'name': 'BalancedResourceAllocation', 'weight': 1}, + {'name': 'SelectorSpreadPriority', 'weight': 1} + ]) + + if short_version == '3.2': + priorities.extend([ + {'name': 'LeastRequestedPriority', 'weight': 1}, + {'name': 'BalancedResourceAllocation', 'weight': 1}, + {'name': 'SelectorSpreadPriority', 'weight': 1}, + {'name': 'NodeAffinityPriority', 'weight': 1} + ]) + + if short_version == '3.3': + priorities.extend([ + {'name': 'LeastRequestedPriority', 'weight': 1}, + {'name': 'BalancedResourceAllocation', 'weight': 1}, + {'name': 'SelectorSpreadPriority', 'weight': 1}, + {'name': 'NodeAffinityPriority', 'weight': 1}, + {'name': 'TaintTolerationPriority', 'weight': 1} + ]) + + if short_version == '3.4': + priorities.extend([ + {'name': 'LeastRequestedPriority', 'weight': 1}, + {'name': 'BalancedResourceAllocation', 'weight': 1}, + {'name': 'SelectorSpreadPriority', 'weight': 1}, + {'name': 'NodePreferAvoidPodsPriority', 'weight': 10000}, + {'name': 'NodeAffinityPriority', 'weight': 1}, + {'name': 'TaintTolerationPriority', 'weight': 1}, + {'name': 'InterPodAffinityPriority', 'weight': 1} + ]) + + if short_version in ['3.5', '3.6', '3.7', '3.8', '3.9']: + priorities.extend([ + {'name': 'SelectorSpreadPriority', 'weight': 1}, + {'name': 'InterPodAffinityPriority', 'weight': 1}, + {'name': 'LeastRequestedPriority', 'weight': 1}, + {'name': 'BalancedResourceAllocation', 'weight': 1}, + {'name': 'NodePreferAvoidPodsPriority', 'weight': 10000}, + {'name': 'NodeAffinityPriority', 'weight': 1}, + {'name': 'TaintTolerationPriority', 'weight': 1} + ]) + + if zones_enabled: + zone_priority = { + 'name': 'Zone', + 'argument': { + 'serviceAntiAffinity': { + 'label': 'zone' + } + }, + 'weight': 2 + } + priorities.append(zone_priority) + + return priorities diff --git a/roles/openshift_certificate_expiry/test/conftest.py b/roles/lib_utils/test/conftest.py index df948fff0..aabdd4fa1 100644 --- a/roles/openshift_certificate_expiry/test/conftest.py +++ b/roles/lib_utils/test/conftest.py @@ -1,7 +1,15 @@ # pylint: disable=missing-docstring,invalid-name,redefined-outer-name +import os import pytest +import sys + from OpenSSL import crypto +sys.path.insert(1, os.path.join(os.path.dirname(__file__), os.pardir, "lookup_plugins")) + +from openshift_master_facts_default_predicates import LookupModule as PredicatesLookupModule # noqa: E402 +from openshift_master_facts_default_priorities import LookupModule as PrioritiesLookupModule # noqa: E402 + # Parameter list for valid_cert fixture VALID_CERTIFICATE_PARAMS = [ { @@ -117,3 +125,48 @@ def valid_cert(request, ca): 'cert_file': cert_file, 'cert': cert } + + +@pytest.fixture() +def predicates_lookup(): + return PredicatesLookupModule() + + +@pytest.fixture() +def priorities_lookup(): + return PrioritiesLookupModule() + + +@pytest.fixture() +def facts(): + return { + 'openshift': { + 'common': {} + } + } + + +@pytest.fixture(params=[True, False]) +def regions_enabled(request): + return request.param + + +@pytest.fixture(params=[True, False]) +def zones_enabled(request): + return request.param + + +def v_prefix(release): + """Prefix a release number with 'v'.""" + return "v" + release + + +def minor(release): + """Add a suffix to release, making 'X.Y' become 'X.Y.Z'.""" + return release + ".1" + + +@pytest.fixture(params=[str, v_prefix, minor]) +def release_mod(request): + """Modifies a release string to alternative valid values.""" + return request.param diff --git a/roles/openshift_master_facts/test/openshift_master_facts_bad_input_tests.py b/roles/lib_utils/test/openshift_master_facts_bad_input_tests.py index e8da1e04a..e8da1e04a 100644 --- a/roles/openshift_master_facts/test/openshift_master_facts_bad_input_tests.py +++ b/roles/lib_utils/test/openshift_master_facts_bad_input_tests.py diff --git a/roles/openshift_master_facts/test/conftest.py b/roles/lib_utils/test/openshift_master_facts_conftest.py index 140cced73..140cced73 100644 --- a/roles/openshift_master_facts/test/conftest.py +++ b/roles/lib_utils/test/openshift_master_facts_conftest.py diff --git a/roles/openshift_master_facts/test/openshift_master_facts_default_predicates_tests.py b/roles/lib_utils/test/openshift_master_facts_default_predicates_tests.py index 11aad9f03..11aad9f03 100644 --- a/roles/openshift_master_facts/test/openshift_master_facts_default_predicates_tests.py +++ b/roles/lib_utils/test/openshift_master_facts_default_predicates_tests.py diff --git a/roles/openshift_master_facts/test/openshift_master_facts_default_priorities_tests.py b/roles/lib_utils/test/openshift_master_facts_default_priorities_tests.py index 527fc9ff4..527fc9ff4 100644 --- a/roles/openshift_master_facts/test/openshift_master_facts_default_priorities_tests.py +++ b/roles/lib_utils/test/openshift_master_facts_default_priorities_tests.py diff --git a/roles/openshift_certificate_expiry/test/test_fakeopensslclasses.py b/roles/lib_utils/test/test_fakeopensslclasses.py index 8a521a765..8a521a765 100644 --- a/roles/openshift_certificate_expiry/test/test_fakeopensslclasses.py +++ b/roles/lib_utils/test/test_fakeopensslclasses.py diff --git a/roles/openshift_certificate_expiry/test/test_load_and_handle_cert.py b/roles/lib_utils/test/test_load_and_handle_cert.py index 98792e2ee..98792e2ee 100644 --- a/roles/openshift_certificate_expiry/test/test_load_and_handle_cert.py +++ b/roles/lib_utils/test/test_load_and_handle_cert.py diff --git a/roles/openshift_aws/defaults/main.yml b/roles/openshift_aws/defaults/main.yml index 71de24339..a729e8dbd 100644 --- a/roles/openshift_aws/defaults/main.yml +++ b/roles/openshift_aws/defaults/main.yml @@ -98,17 +98,26 @@ openshift_aws_elb_dict: proxy_protocol: True openshift_aws_node_group_config_master_volumes: +- device_name: /dev/sda1 + volume_size: 100 + device_type: gp2 + delete_on_termination: False - device_name: /dev/sdb volume_size: 100 device_type: gp2 delete_on_termination: False openshift_aws_node_group_config_node_volumes: +- device_name: /dev/sda1 + volume_size: 100 + device_type: gp2 + delete_on_termination: True - device_name: /dev/sdb volume_size: 100 device_type: gp2 delete_on_termination: True +# build_instance_tags is a custom filter in role lib_utils openshift_aws_node_group_config_tags: "{{ openshift_aws_clusterid | build_instance_tags }}" openshift_aws_node_group_termination_policy: Default openshift_aws_node_group_replace_instances: [] @@ -201,6 +210,7 @@ openshift_aws_node_group_config: openshift_aws_elb_tags: "{{ openshift_aws_kube_tags }}" openshift_aws_elb_az_load_balancing: False +# build_instance_tags is a custom filter in role lib_utils openshift_aws_kube_tags: "{{ openshift_aws_clusterid | build_instance_tags }}" openshift_aws_elb_security_groups: "{{ openshift_aws_launch_config_security_groups }}" @@ -291,3 +301,7 @@ openshift_aws_node_user_data: '' openshift_aws_node_config_namespace: openshift-node openshift_aws_masters_groups: masters,etcd,nodes + +# By default, don't delete things like the shared IAM instance +# profile and uploaded ssh keys +openshift_aws_enable_uninstall_shared_objects: False diff --git a/roles/openshift_aws/tasks/accept_nodes.yml b/roles/openshift_aws/tasks/accept_nodes.yml index c2a2cea30..db30fe5c9 100644 --- a/roles/openshift_aws/tasks/accept_nodes.yml +++ b/roles/openshift_aws/tasks/accept_nodes.yml @@ -1,4 +1,6 @@ --- +- include_tasks: setup_master_group.yml + - name: fetch masters ec2_instance_facts: region: "{{ openshift_aws_region | default('us-east-1') }}" @@ -36,4 +38,4 @@ nodes: "{{ instancesout.instances|map(attribute='private_dns_name') | list }}" timeout: 60 register: nodeout - delegate_to: "{{ mastersout.instances[0].public_ip_address }}" + delegate_to: "{{ groups.masters.0 }}" diff --git a/roles/openshift_aws/tasks/build_node_group.yml b/roles/openshift_aws/tasks/build_node_group.yml index 9485cc3ac..a9f9cc3c4 100644 --- a/roles/openshift_aws/tasks/build_node_group.yml +++ b/roles/openshift_aws/tasks/build_node_group.yml @@ -43,6 +43,7 @@ - name: set the value for the deployment_serial and the current asgs set_fact: + # scale_groups_serial is a custom filter in role lib_utils l_deployment_serial: "{{ openshift_aws_node_group_deployment_serial if openshift_aws_node_group_deployment_serial is defined else asgs.results | scale_groups_serial(openshift_aws_node_group_upgrade) }}" openshift_aws_current_asgs: "{{ asgs.results | map(attribute='auto_scaling_group_name') | list | union(openshift_aws_current_asgs) }}" diff --git a/roles/openshift_aws/tasks/provision.yml b/roles/openshift_aws/tasks/provision.yml index 786a2e4cf..2b5f317d8 100644 --- a/roles/openshift_aws/tasks/provision.yml +++ b/roles/openshift_aws/tasks/provision.yml @@ -1,23 +1,6 @@ --- -- when: openshift_aws_create_iam_cert | bool - name: create the iam_cert for elb certificate - include_tasks: iam_cert.yml - -- when: openshift_aws_create_s3 | bool - name: create s3 bucket for registry - include_tasks: s3.yml - - include_tasks: vpc_and_subnet_id.yml -- name: create elbs - include_tasks: elb.yml - with_dict: "{{ openshift_aws_elb_dict }}" - vars: - l_elb_security_groups: "{{ openshift_aws_elb_security_groups }}" - l_openshift_aws_elb_name_dict: "{{ openshift_aws_elb_name_dict }}" - loop_control: - loop_var: l_elb_dict_item - - name: include scale group creation for master include_tasks: build_node_group.yml with_items: "{{ openshift_aws_master_group }}" diff --git a/roles/openshift_aws/tasks/provision_elb.yml b/roles/openshift_aws/tasks/provision_elb.yml new file mode 100644 index 000000000..a52f63bd5 --- /dev/null +++ b/roles/openshift_aws/tasks/provision_elb.yml @@ -0,0 +1,15 @@ +--- +- when: openshift_aws_create_iam_cert | bool + name: create the iam_cert for elb certificate + include_tasks: iam_cert.yml + +- include_tasks: vpc_and_subnet_id.yml + +- name: create elbs + include_tasks: elb.yml + with_dict: "{{ openshift_aws_elb_dict }}" + vars: + l_elb_security_groups: "{{ openshift_aws_elb_security_groups }}" + l_openshift_aws_elb_name_dict: "{{ openshift_aws_elb_name_dict }}" + loop_control: + loop_var: l_elb_dict_item diff --git a/roles/openshift_aws/tasks/provision_nodes.yml b/roles/openshift_aws/tasks/provision_nodes.yml index d82f18574..9105b5b4c 100644 --- a/roles/openshift_aws/tasks/provision_nodes.yml +++ b/roles/openshift_aws/tasks/provision_nodes.yml @@ -2,25 +2,12 @@ # Get bootstrap config token # bootstrap should be created on first master # need to fetch it and shove it into cloud data -- name: fetch master instances - ec2_instance_facts: - region: "{{ openshift_aws_region }}" - filters: - "tag:clusterid": "{{ openshift_aws_clusterid }}" - "tag:host-type": master - instance-state-name: running - register: instancesout - retries: 20 - delay: 3 - until: - - "'instances' in instancesout" - - instancesout.instances|length > 0 +- include_tasks: setup_master_group.yml - name: slurp down the bootstrap.kubeconfig slurp: src: /etc/origin/master/bootstrap.kubeconfig - delegate_to: "{{ instancesout.instances[0].public_ip_address }}" - remote_user: root + delegate_to: "{{ groups.masters.0 }}" register: bootstrap - name: set_fact for kubeconfig token diff --git a/roles/openshift_aws/tasks/uninstall_security_group.yml b/roles/openshift_aws/tasks/uninstall_security_group.yml new file mode 100644 index 000000000..55d40e8ec --- /dev/null +++ b/roles/openshift_aws/tasks/uninstall_security_group.yml @@ -0,0 +1,14 @@ +--- +- name: delete the node group sgs + oo_ec2_group: + state: absent + name: "{{ item.value.name}}" + region: "{{ openshift_aws_region }}" + with_dict: "{{ openshift_aws_node_security_groups }}" + +- name: delete the k8s sgs for the node group + oo_ec2_group: + state: absent + name: "{{ item.value.name }}_k8s" + region: "{{ openshift_aws_region }}" + with_dict: "{{ openshift_aws_node_security_groups }}" diff --git a/roles/openshift_aws/tasks/uninstall_ssh_keys.yml b/roles/openshift_aws/tasks/uninstall_ssh_keys.yml new file mode 100644 index 000000000..27e42da53 --- /dev/null +++ b/roles/openshift_aws/tasks/uninstall_ssh_keys.yml @@ -0,0 +1,9 @@ +--- +- name: Remove the public keys for the user(s) + ec2_key: + state: absent + name: "{{ item.key_name }}" + region: "{{ openshift_aws_region }}" + with_items: "{{ openshift_aws_users }}" + no_log: True + when: openshift_aws_enable_uninstall_shared_objects | bool diff --git a/roles/openshift_aws/tasks/uninstall_vpc.yml b/roles/openshift_aws/tasks/uninstall_vpc.yml new file mode 100644 index 000000000..ecf39f694 --- /dev/null +++ b/roles/openshift_aws/tasks/uninstall_vpc.yml @@ -0,0 +1,36 @@ +--- +- name: Fetch the VPC for the vpc.id + ec2_vpc_net_facts: + region: "{{ openshift_aws_region }}" + filters: + "tag:Name": "{{ openshift_aws_clusterid }}" + register: vpcout +- debug: + var: vpcout + verbosity: 1 + +- when: vpcout.vpcs | length > 0 + block: + - name: delete the vpc igw + ec2_vpc_igw: + state: absent + region: "{{ openshift_aws_region }}" + vpc_id: "{{ vpcout.vpcs[0].id }}" + register: igw + + - name: delete the vpc subnets + ec2_vpc_subnet: + state: absent + region: "{{ openshift_aws_region }}" + vpc_id: "{{ vpcout.vpcs[0].id }}" + cidr: "{{ item.cidr }}" + az: "{{ item.az }}" + with_items: "{{ openshift_aws_vpc.subnets[openshift_aws_region] }}" + + - name: Delete AWS VPC + ec2_vpc_net: + state: absent + region: "{{ openshift_aws_region }}" + name: "{{ openshift_aws_clusterid }}" + cidr_block: "{{ openshift_aws_vpc.cidr }}" + register: vpc diff --git a/roles/openshift_aws/tasks/wait_for_groups.yml b/roles/openshift_aws/tasks/wait_for_groups.yml index 1f4ef3e1c..3ad876e37 100644 --- a/roles/openshift_aws/tasks/wait_for_groups.yml +++ b/roles/openshift_aws/tasks/wait_for_groups.yml @@ -8,6 +8,7 @@ tags: "{{ {'kubernetes.io/cluster/' ~ openshift_aws_clusterid: openshift_aws_clusterid } }}" register: qasg + # scale_groups_match_capacity is a custom filter in role lib_utils until: qasg | json_query('results[*]') | scale_groups_match_capacity | bool delay: 10 retries: 60 diff --git a/roles/openshift_buildoverrides/vars/main.yml b/roles/openshift_buildoverrides/vars/main.yml index cf49a6ebf..df53280c8 100644 --- a/roles/openshift_buildoverrides/vars/main.yml +++ b/roles/openshift_buildoverrides/vars/main.yml @@ -9,3 +9,4 @@ buildoverrides_yaml: imageLabels: "{{ openshift_buildoverrides_image_labels | default(None) }}" nodeSelector: "{{ openshift_buildoverrides_nodeselectors | default(None) }}" annotations: "{{ openshift_buildoverrides_annotations | default(None) }}" + tolerations: "{{ openshift_buildoverrides_tolerations | default(None) }}" diff --git a/roles/openshift_ca/tasks/main.yml b/roles/openshift_ca/tasks/main.yml index b94cd9fba..9c8534c74 100644 --- a/roles/openshift_ca/tasks/main.yml +++ b/roles/openshift_ca/tasks/main.yml @@ -19,7 +19,8 @@ - name: Reload generated facts openshift_facts: - when: hostvars[openshift_ca_host].install_result is changed + when: + - hostvars[openshift_ca_host].install_result | default({'changed':false}) is changed - name: Create openshift_ca_config_dir if it does not exist file: diff --git a/roles/openshift_certificate_expiry/tasks/main.yml b/roles/openshift_certificate_expiry/tasks/main.yml index 8dea2c07f..7062b5060 100644 --- a/roles/openshift_certificate_expiry/tasks/main.yml +++ b/roles/openshift_certificate_expiry/tasks/main.yml @@ -16,7 +16,9 @@ - name: Generate the result JSON string run_once: yes - set_fact: json_result_string="{{ hostvars|oo_cert_expiry_results_to_json(play_hosts) }}" + set_fact: + # oo_cert_expiry_results_to_json is a custom filter in role lib_utils + json_result_string: "{{ hostvars|oo_cert_expiry_results_to_json(play_hosts) }}" when: openshift_certificate_expiry_save_json_results|bool - name: Generate results JSON file diff --git a/roles/openshift_cli/tasks/main.yml b/roles/openshift_cli/tasks/main.yml index 37bed9dbe..ae8d1ace0 100644 --- a/roles/openshift_cli/tasks/main.yml +++ b/roles/openshift_cli/tasks/main.yml @@ -12,6 +12,7 @@ register: pull_result changed_when: "'Downloaded newer image' in pull_result.stdout" + # openshift_container_binary_sync is a custom module in lib_utils - name: Copy client binaries/symlinks out of CLI image for use on the host openshift_container_binary_sync: image: "{{ openshift_cli_image }}" @@ -28,6 +29,7 @@ register: pull_result changed_when: "'Pulling layer' in pull_result.stdout" + # openshift_container_binary_sync is a custom module in lib_utils - name: Copy client binaries/symlinks out of CLI image for use on the host openshift_container_binary_sync: image: "{{ '' if system_images_registry == 'docker' else system_images_registry + '/' }}{{ openshift_cli_image }}" diff --git a/roles/openshift_cloud_provider/tasks/main.yml b/roles/openshift_cloud_provider/tasks/main.yml index dff492a69..3513577fa 100644 --- a/roles/openshift_cloud_provider/tasks/main.yml +++ b/roles/openshift_cloud_provider/tasks/main.yml @@ -19,3 +19,6 @@ - include_tasks: gce.yml when: cloudprovider_is_gce | bool + +- include_tasks: vsphere.yml + when: cloudprovider_is_vsphere | bool diff --git a/roles/openshift_cloud_provider/tasks/vsphere.yml b/roles/openshift_cloud_provider/tasks/vsphere.yml new file mode 100644 index 000000000..3a33df241 --- /dev/null +++ b/roles/openshift_cloud_provider/tasks/vsphere.yml @@ -0,0 +1,6 @@ +--- +- name: Create cloud config + template: + dest: "{{ openshift.common.config_base }}/cloudprovider/vsphere.conf" + src: vsphere.conf.j2 + when: openshift_cloudprovider_vsphere_username is defined and openshift_cloudprovider_vsphere_password is defined and openshift_cloudprovider_vsphere_host is defined and openshift_cloudprovider_vsphere_datacenter is defined and openshift_cloudprovider_vsphere_datastore is defined diff --git a/roles/openshift_cloud_provider/templates/openstack.conf.j2 b/roles/openshift_cloud_provider/templates/openstack.conf.j2 index 313ee02b4..30f18ffa9 100644 --- a/roles/openshift_cloud_provider/templates/openstack.conf.j2 +++ b/roles/openshift_cloud_provider/templates/openstack.conf.j2 @@ -19,3 +19,7 @@ region = {{ openshift_cloudprovider_openstack_region }} [LoadBalancer] subnet-id = {{ openshift_cloudprovider_openstack_lb_subnet_id }} {% endif %} +{% if openshift_cloudprovider_openstack_blockstorage_version is defined %} +[BlockStorage] +bs-version={{ openshift_cloudprovider_openstack_blockstorage_version }} +{% endif %}
\ No newline at end of file diff --git a/roles/openshift_cloud_provider/templates/vsphere.conf.j2 b/roles/openshift_cloud_provider/templates/vsphere.conf.j2 new file mode 100644 index 000000000..84e5e371c --- /dev/null +++ b/roles/openshift_cloud_provider/templates/vsphere.conf.j2 @@ -0,0 +1,15 @@ +[Global] +user = "{{ openshift_cloudprovider_vsphere_username }}" +password = "{{ openshift_cloudprovider_vsphere_password }}" +server = "{{ openshift_cloudprovider_vsphere_host }}" +port = 443 +insecure-flag = 1 +datacenter = {{ openshift_cloudprovider_vsphere_datacenter }} +datastore = {{ openshift_cloudprovider_vsphere_datastore }} +{% if openshift_cloudprovider_vsphere_folder is defined %} +working-dir = /{{ openshift_cloudprovider_vsphere_datacenter }}/vm/{{ openshift_cloudprovider_vsphere_folder }}/ +{% else %} +working-dir = /{{ openshift_cloudprovider_vsphere_datacenter }}/vm/ +{% endif %} +[Disk] +scsicontrollertype = pvscsi diff --git a/roles/openshift_cloud_provider/vars/main.yml b/roles/openshift_cloud_provider/vars/main.yml index c9d953f58..e71db80b9 100644 --- a/roles/openshift_cloud_provider/vars/main.yml +++ b/roles/openshift_cloud_provider/vars/main.yml @@ -3,3 +3,4 @@ has_cloudprovider: "{{ openshift_cloudprovider_kind | default(None) != None }}" cloudprovider_is_aws: "{{ has_cloudprovider | bool and openshift_cloudprovider_kind == 'aws' }}" cloudprovider_is_openstack: "{{ has_cloudprovider | bool and openshift_cloudprovider_kind == 'openstack' }}" cloudprovider_is_gce: "{{ has_cloudprovider | bool and openshift_cloudprovider_kind == 'gce' }}" +cloudprovider_is_vsphere: "{{ has_cloudprovider | bool and openshift_cloudprovider_kind == 'vsphere' }}" diff --git a/roles/openshift_examples/examples-sync.sh b/roles/openshift_examples/examples-sync.sh index 68a0e8857..648bf7293 100755 --- a/roles/openshift_examples/examples-sync.sh +++ b/roles/openshift_examples/examples-sync.sh @@ -6,7 +6,7 @@ # This script should be run from openshift-ansible/roles/openshift_examples XPAAS_VERSION=ose-v1.4.7 -ORIGIN_VERSION=${1:-v3.7} +ORIGIN_VERSION=${1:-v3.9} RHAMP_TAG=2.0.0.GA EXAMPLES_BASE=$(pwd)/files/examples/${ORIGIN_VERSION} find ${EXAMPLES_BASE} -name '*.json' -delete diff --git a/roles/openshift_examples/files/examples/v3.9/db-templates/mariadb-persistent-template.json b/roles/openshift_examples/files/examples/v3.9/db-templates/mariadb-persistent-template.json index 217ef11dd..92be8f42e 100644 --- a/roles/openshift_examples/files/examples/v3.9/db-templates/mariadb-persistent-template.json +++ b/roles/openshift_examples/files/examples/v3.9/db-templates/mariadb-persistent-template.json @@ -4,7 +4,7 @@ "metadata": { "name": "mariadb-persistent", "annotations": { - "openshift.io/display-name": "MariaDB (Persistent)", + "openshift.io/display-name": "MariaDB", "description": "MariaDB database service, with persistent storage. For more information about using this template, including OpenShift considerations, see https://github.com/sclorg/mariadb-container/blob/master/10.1/README.md.\n\nNOTE: Scaling to more than one replica is not supported. You must have persistent volumes available in your cluster to use this template.", "iconClass": "icon-mariadb", "tags": "database,mariadb", diff --git a/roles/openshift_examples/files/examples/v3.9/db-templates/mongodb-persistent-template.json b/roles/openshift_examples/files/examples/v3.9/db-templates/mongodb-persistent-template.json index 97e4128a4..4e3e64d48 100644 --- a/roles/openshift_examples/files/examples/v3.9/db-templates/mongodb-persistent-template.json +++ b/roles/openshift_examples/files/examples/v3.9/db-templates/mongodb-persistent-template.json @@ -4,7 +4,7 @@ "metadata": { "name": "mongodb-persistent", "annotations": { - "openshift.io/display-name": "MongoDB (Persistent)", + "openshift.io/display-name": "MongoDB", "description": "MongoDB database service, with persistent storage. For more information about using this template, including OpenShift considerations, see https://github.com/sclorg/mongodb-container/blob/master/3.2/README.md.\n\nNOTE: Scaling to more than one replica is not supported. You must have persistent volumes available in your cluster to use this template.", "iconClass": "icon-mongodb", "tags": "database,mongodb", diff --git a/roles/openshift_examples/files/examples/v3.9/db-templates/mysql-persistent-template.json b/roles/openshift_examples/files/examples/v3.9/db-templates/mysql-persistent-template.json index 48ac114fd..6ac80f3a0 100644 --- a/roles/openshift_examples/files/examples/v3.9/db-templates/mysql-persistent-template.json +++ b/roles/openshift_examples/files/examples/v3.9/db-templates/mysql-persistent-template.json @@ -4,7 +4,7 @@ "metadata": { "name": "mysql-persistent", "annotations": { - "openshift.io/display-name": "MySQL (Persistent)", + "openshift.io/display-name": "MySQL", "description": "MySQL database service, with persistent storage. For more information about using this template, including OpenShift considerations, see https://github.com/sclorg/mysql-container/blob/master/5.7/README.md.\n\nNOTE: Scaling to more than one replica is not supported. You must have persistent volumes available in your cluster to use this template.", "iconClass": "icon-mysql-database", "tags": "database,mysql", diff --git a/roles/openshift_examples/files/examples/v3.9/db-templates/postgresql-persistent-template.json b/roles/openshift_examples/files/examples/v3.9/db-templates/postgresql-persistent-template.json index 8a2d23907..190509112 100644 --- a/roles/openshift_examples/files/examples/v3.9/db-templates/postgresql-persistent-template.json +++ b/roles/openshift_examples/files/examples/v3.9/db-templates/postgresql-persistent-template.json @@ -4,7 +4,7 @@ "metadata": { "name": "postgresql-persistent", "annotations": { - "openshift.io/display-name": "PostgreSQL (Persistent)", + "openshift.io/display-name": "PostgreSQL", "description": "PostgreSQL database service, with persistent storage. For more information about using this template, including OpenShift considerations, see https://github.com/sclorg/postgresql-container/blob/master/9.5.\n\nNOTE: Scaling to more than one replica is not supported. You must have persistent volumes available in your cluster to use this template.", "iconClass": "icon-postgresql", "tags": "database,postgresql", diff --git a/roles/openshift_examples/files/examples/v3.9/db-templates/redis-persistent-template.json b/roles/openshift_examples/files/examples/v3.9/db-templates/redis-persistent-template.json index e0e0a88d5..d1103d3af 100644 --- a/roles/openshift_examples/files/examples/v3.9/db-templates/redis-persistent-template.json +++ b/roles/openshift_examples/files/examples/v3.9/db-templates/redis-persistent-template.json @@ -4,7 +4,7 @@ "metadata": { "name": "redis-persistent", "annotations": { - "openshift.io/display-name": "Redis (Persistent)", + "openshift.io/display-name": "Redis", "description": "Redis in-memory data structure store, with persistent storage. For more information about using this template, including OpenShift considerations, see https://github.com/sclorg/redis-container/blob/master/3.2.\n\nNOTE: You must have persistent volumes available in your cluster to use this template.", "iconClass": "icon-redis", "tags": "database,redis", diff --git a/roles/openshift_examples/files/examples/v3.9/image-streams/image-streams-centos7.json b/roles/openshift_examples/files/examples/v3.9/image-streams/image-streams-centos7.json index e7af160d9..ad17b709e 100644 --- a/roles/openshift_examples/files/examples/v3.9/image-streams/image-streams-centos7.json +++ b/roles/openshift_examples/files/examples/v3.9/image-streams/image-streams-centos7.json @@ -407,7 +407,7 @@ "annotations": { "openshift.io/display-name": "Python (Latest)", "openshift.io/provider-display-name": "Red Hat, Inc.", - "description": "Build and run Python applications on CentOS 7. For more information about using this builder image, including OpenShift considerations, see https://github.com/sclorg/s2i-python-container/blob/master/3.5/README.md.\n\nWARNING: By selecting this tag, your application will automatically update to use the latest version of Python available on OpenShift, including major versions updates.", + "description": "Build and run Python applications on CentOS 7. For more information about using this builder image, including OpenShift considerations, see https://github.com/sclorg/s2i-python-container/blob/master/3.6/README.md.\n\nWARNING: By selecting this tag, your application will automatically update to use the latest version of Python available on OpenShift, including major versions updates.", "iconClass": "icon-python", "tags": "builder,python", "supports":"python", @@ -415,7 +415,7 @@ }, "from": { "kind": "ImageStreamTag", - "name": "3.5" + "name": "3.6" } }, { @@ -485,6 +485,23 @@ "kind": "DockerImage", "name": "centos/python-35-centos7:latest" } + }, + { + "name": "3.6", + "annotations": { + "openshift.io/display-name": "Python 3.6", + "openshift.io/provider-display-name": "Red Hat, Inc.", + "description": "Build and run Python 3.6 applications on CentOS 7. For more information about using this builder image, including OpenShift considerations, see https://github.com/sclorg/s2i-python-container/blob/master/3.6/README.md.", + "iconClass": "icon-python", + "tags": "builder,python", + "supports":"python:3.6,python", + "version": "3.6", + "sampleRepo": "https://github.com/openshift/django-ex.git" + }, + "from": { + "kind": "DockerImage", + "name": "centos/python-36-centos7:latest" + } } ] } @@ -944,7 +961,7 @@ }, "from": { "kind": "DockerImage", - "name": "openshift/jenkins-2-centos7:latest" + "name": "openshift/jenkins-2-centos7:v3.9" } } ] diff --git a/roles/openshift_examples/files/examples/v3.9/image-streams/image-streams-rhel7.json b/roles/openshift_examples/files/examples/v3.9/image-streams/image-streams-rhel7.json index 2b082fc75..efc8705f4 100644 --- a/roles/openshift_examples/files/examples/v3.9/image-streams/image-streams-rhel7.json +++ b/roles/openshift_examples/files/examples/v3.9/image-streams/image-streams-rhel7.json @@ -407,7 +407,7 @@ "annotations": { "openshift.io/display-name": "Python (Latest)", "openshift.io/provider-display-name": "Red Hat, Inc.", - "description": "Build and run Python applications on RHEL 7. For more information about using this builder image, including OpenShift considerations, see https://github.com/sclorg/s2i-python-container/blob/master/3.5/README.md.\n\nWARNING: By selecting this tag, your application will automatically update to use the latest version of Python available on OpenShift, including major versions updates.", + "description": "Build and run Python applications on RHEL 7. For more information about using this builder image, including OpenShift considerations, see https://github.com/sclorg/s2i-python-container/blob/master/3.6/README.md.\n\nWARNING: By selecting this tag, your application will automatically update to use the latest version of Python available on OpenShift, including major versions updates.", "iconClass": "icon-python", "tags": "builder,python", "supports":"python", @@ -415,7 +415,7 @@ }, "from": { "kind": "ImageStreamTag", - "name": "3.5" + "name": "3.6" } }, { @@ -485,6 +485,23 @@ "kind": "DockerImage", "name": "registry.access.redhat.com/rhscl/python-35-rhel7:latest" } + }, + { + "name": "3.6", + "annotations": { + "openshift.io/display-name": "Python 3.6", + "openshift.io/provider-display-name": "Red Hat, Inc.", + "description": "Build and run Python 3.6 applications on RHEL 7. For more information about using this builder image, including OpenShift considerations, see https://github.com/sclorg/s2i-python-container/blob/master/3.6/README.md.", + "iconClass": "icon-python", + "tags": "builder,python", + "supports":"python:3.6,python", + "version": "3.6", + "sampleRepo": "https://github.com/openshift/django-ex.git" + }, + "from": { + "kind": "DockerImage", + "name": "registry.access.redhat.com/rhscl/python-36-rhel7:latest" + } } ] } @@ -846,7 +863,7 @@ }, "from": { "kind": "DockerImage", - "name": "registry.access.redhat.com/openshift3/jenkins-2-rhel7:latest" + "name": "registry.access.redhat.com/openshift3/jenkins-2-rhel7:v3.9" } } ] diff --git a/roles/openshift_examples/files/examples/v3.9/quickstart-templates/cakephp-mysql-persistent.json b/roles/openshift_examples/files/examples/v3.9/quickstart-templates/cakephp-mysql-persistent.json index 86ddc184a..40b4eaa81 100644 --- a/roles/openshift_examples/files/examples/v3.9/quickstart-templates/cakephp-mysql-persistent.json +++ b/roles/openshift_examples/files/examples/v3.9/quickstart-templates/cakephp-mysql-persistent.json @@ -4,7 +4,7 @@ "metadata": { "name": "cakephp-mysql-persistent", "annotations": { - "openshift.io/display-name": "CakePHP + MySQL (Persistent)", + "openshift.io/display-name": "CakePHP + MySQL", "description": "An example CakePHP application with a MySQL database. For more information about using this template, including OpenShift considerations, see https://github.com/openshift/cakephp-ex/blob/master/README.md.", "tags": "quickstart,php,cakephp", "iconClass": "icon-php", @@ -17,7 +17,8 @@ }, "message": "The following service(s) have been created in your project: ${NAME}, ${DATABASE_SERVICE_NAME}.\n\nFor more information about using this template, including OpenShift considerations, see https://github.com/openshift/cake-ex/blob/master/README.md.", "labels": { - "template": "cakephp-mysql-persistent" + "template": "cakephp-mysql-persistent", + "app": "cakephp-mysql-persistent" }, "objects": [ { diff --git a/roles/openshift_examples/files/examples/v3.9/quickstart-templates/cakephp-mysql.json b/roles/openshift_examples/files/examples/v3.9/quickstart-templates/cakephp-mysql.json index 3c964bd6a..ecd90e495 100644 --- a/roles/openshift_examples/files/examples/v3.9/quickstart-templates/cakephp-mysql.json +++ b/roles/openshift_examples/files/examples/v3.9/quickstart-templates/cakephp-mysql.json @@ -17,7 +17,8 @@ }, "message": "The following service(s) have been created in your project: ${NAME}, ${DATABASE_SERVICE_NAME}.\n\nFor more information about using this template, including OpenShift considerations, see https://github.com/openshift/cake-ex/blob/master/README.md.", "labels": { - "template": "cakephp-mysql-example" + "template": "cakephp-mysql-example", + "app": "cakephp-mysql-example" }, "objects": [ { diff --git a/roles/openshift_examples/files/examples/v3.9/quickstart-templates/dancer-mysql-persistent.json b/roles/openshift_examples/files/examples/v3.9/quickstart-templates/dancer-mysql-persistent.json index 0a10c5fbc..17a155600 100644 --- a/roles/openshift_examples/files/examples/v3.9/quickstart-templates/dancer-mysql-persistent.json +++ b/roles/openshift_examples/files/examples/v3.9/quickstart-templates/dancer-mysql-persistent.json @@ -4,7 +4,7 @@ "metadata": { "name": "dancer-mysql-persistent", "annotations": { - "openshift.io/display-name": "Dancer + MySQL (Persistent)", + "openshift.io/display-name": "Dancer + MySQL", "description": "An example Dancer application with a MySQL database. For more information about using this template, including OpenShift considerations, see https://github.com/openshift/dancer-ex/blob/master/README.md.", "tags": "quickstart,perl,dancer", "iconClass": "icon-perl", @@ -17,7 +17,8 @@ }, "message": "The following service(s) have been created in your project: ${NAME}, ${DATABASE_SERVICE_NAME}.\n\nFor more information about using this template, including OpenShift considerations, see https://github.com/openshift/dancer-ex/blob/master/README.md.", "labels": { - "template": "dancer-mysql-persistent" + "template": "dancer-mysql-persistent", + "app": "dancer-mysql-persistent" }, "objects": [ { diff --git a/roles/openshift_examples/files/examples/v3.9/quickstart-templates/dancer-mysql.json b/roles/openshift_examples/files/examples/v3.9/quickstart-templates/dancer-mysql.json index 6122d5436..abf711535 100644 --- a/roles/openshift_examples/files/examples/v3.9/quickstart-templates/dancer-mysql.json +++ b/roles/openshift_examples/files/examples/v3.9/quickstart-templates/dancer-mysql.json @@ -17,7 +17,8 @@ }, "message": "The following service(s) have been created in your project: ${NAME}, ${DATABASE_SERVICE_NAME}.\n\nFor more information about using this template, including OpenShift considerations, see https://github.com/openshift/dancer-ex/blob/master/README.md.", "labels": { - "template": "dancer-mysql-example" + "template": "dancer-mysql-example", + "app": "dancer-mysql-example" }, "objects": [ { diff --git a/roles/openshift_examples/files/examples/v3.9/quickstart-templates/django-postgresql-persistent.json b/roles/openshift_examples/files/examples/v3.9/quickstart-templates/django-postgresql-persistent.json index f3b5838fa..c8dab0b53 100644 --- a/roles/openshift_examples/files/examples/v3.9/quickstart-templates/django-postgresql-persistent.json +++ b/roles/openshift_examples/files/examples/v3.9/quickstart-templates/django-postgresql-persistent.json @@ -4,7 +4,7 @@ "metadata": { "name": "django-psql-persistent", "annotations": { - "openshift.io/display-name": "Django + PostgreSQL (Persistent)", + "openshift.io/display-name": "Django + PostgreSQL", "description": "An example Django application with a PostgreSQL database. For more information about using this template, including OpenShift considerations, see https://github.com/openshift/django-ex/blob/master/README.md.", "tags": "quickstart,python,django", "iconClass": "icon-python", @@ -17,7 +17,8 @@ }, "message": "The following service(s) have been created in your project: ${NAME}, ${DATABASE_SERVICE_NAME}.\n\nFor more information about using this template, including OpenShift considerations, see https://github.com/openshift/django-ex/blob/master/README.md.", "labels": { - "template": "django-psql-persistent" + "template": "django-psql-persistent", + "app": "django-psql-persistent" }, "objects": [ { diff --git a/roles/openshift_examples/files/examples/v3.9/quickstart-templates/django-postgresql.json b/roles/openshift_examples/files/examples/v3.9/quickstart-templates/django-postgresql.json index b21295df2..6395defda 100644 --- a/roles/openshift_examples/files/examples/v3.9/quickstart-templates/django-postgresql.json +++ b/roles/openshift_examples/files/examples/v3.9/quickstart-templates/django-postgresql.json @@ -17,7 +17,8 @@ }, "message": "The following service(s) have been created in your project: ${NAME}, ${DATABASE_SERVICE_NAME}.\n\nFor more information about using this template, including OpenShift considerations, see https://github.com/openshift/django-ex/blob/master/README.md.", "labels": { - "template": "django-psql-example" + "template": "django-psql-example", + "app": "django-psql-example" }, "objects": [ { diff --git a/roles/openshift_examples/files/examples/v3.9/quickstart-templates/httpd.json b/roles/openshift_examples/files/examples/v3.9/quickstart-templates/httpd.json index 3771280bf..e944f21a5 100644 --- a/roles/openshift_examples/files/examples/v3.9/quickstart-templates/httpd.json +++ b/roles/openshift_examples/files/examples/v3.9/quickstart-templates/httpd.json @@ -17,7 +17,8 @@ }, "message": "The following service(s) have been created in your project: ${NAME}.\n\nFor more information about using this template, including OpenShift considerations, see https://github.com/openshift/httpd-ex/blob/master/README.md.", "labels": { - "template": "httpd-example" + "template": "httpd-example", + "app": "httpd-example" }, "objects": [ { @@ -198,12 +199,7 @@ } }, "env": [ - ], - "resources": { - "limits": { - "memory": "${MEMORY_LIMIT}" - } - } + ] } ] } diff --git a/roles/openshift_examples/files/examples/v3.9/quickstart-templates/jenkins-ephemeral-template.json b/roles/openshift_examples/files/examples/v3.9/quickstart-templates/jenkins-ephemeral-template.json index 28b4b9d81..87ae6ed14 100644 --- a/roles/openshift_examples/files/examples/v3.9/quickstart-templates/jenkins-ephemeral-template.json +++ b/roles/openshift_examples/files/examples/v3.9/quickstart-templates/jenkins-ephemeral-template.json @@ -15,6 +15,10 @@ } }, "message": "A Jenkins service has been created in your project. Log into Jenkins with your OpenShift account. The tutorial at https://github.com/openshift/origin/blob/master/examples/jenkins/README.md contains more information about using this template.", + "labels": { + "app": "jenkins-ephemeral", + "template": "jenkins-ephemeral-template" + }, "objects": [ { "kind": "Route", @@ -275,10 +279,7 @@ "name": "JENKINS_IMAGE_STREAM_TAG", "displayName": "Jenkins ImageStreamTag", "description": "Name of the ImageStreamTag to be used for the Jenkins image.", - "value": "jenkins:latest" + "value": "jenkins:2" } - ], - "labels": { - "template": "jenkins-ephemeral-template" - } + ] } diff --git a/roles/openshift_examples/files/examples/v3.9/quickstart-templates/jenkins-persistent-template.json b/roles/openshift_examples/files/examples/v3.9/quickstart-templates/jenkins-persistent-template.json index 4915bb12c..95d15b55f 100644 --- a/roles/openshift_examples/files/examples/v3.9/quickstart-templates/jenkins-persistent-template.json +++ b/roles/openshift_examples/files/examples/v3.9/quickstart-templates/jenkins-persistent-template.json @@ -4,7 +4,7 @@ "metadata": { "name": "jenkins-persistent", "annotations": { - "openshift.io/display-name": "Jenkins (Persistent)", + "openshift.io/display-name": "Jenkins", "description": "Jenkins service, with persistent storage.\n\nNOTE: You must have persistent volumes available in your cluster to use this template.", "iconClass": "icon-jenkins", "tags": "instant-app,jenkins", @@ -15,6 +15,10 @@ } }, "message": "A Jenkins service has been created in your project. Log into Jenkins with your OpenShift account. The tutorial at https://github.com/openshift/origin/blob/master/examples/jenkins/README.md contains more information about using this template.", + "labels": { + "app": "jenkins-persistent", + "template": "jenkins-persistent-template" + }, "objects": [ { "kind": "Route", @@ -299,10 +303,7 @@ "name": "JENKINS_IMAGE_STREAM_TAG", "displayName": "Jenkins ImageStreamTag", "description": "Name of the ImageStreamTag to be used for the Jenkins image.", - "value": "jenkins:latest" + "value": "jenkins:2" } - ], - "labels": { - "template": "jenkins-persistent-template" - } + ] } diff --git a/roles/openshift_examples/files/examples/v3.9/quickstart-templates/nodejs-mongodb-persistent.json b/roles/openshift_examples/files/examples/v3.9/quickstart-templates/nodejs-mongodb-persistent.json index 7f2a5d804..f04adaa67 100644 --- a/roles/openshift_examples/files/examples/v3.9/quickstart-templates/nodejs-mongodb-persistent.json +++ b/roles/openshift_examples/files/examples/v3.9/quickstart-templates/nodejs-mongodb-persistent.json @@ -4,7 +4,7 @@ "metadata": { "name": "nodejs-mongo-persistent", "annotations": { - "openshift.io/display-name": "Node.js + MongoDB (Persistent)", + "openshift.io/display-name": "Node.js + MongoDB", "description": "An example Node.js application with a MongoDB database. For more information about using this template, including OpenShift considerations, see https://github.com/openshift/nodejs-ex/blob/master/README.md.", "tags": "quickstart,nodejs", "iconClass": "icon-nodejs", @@ -17,7 +17,8 @@ }, "message": "The following service(s) have been created in your project: ${NAME}, ${DATABASE_SERVICE_NAME}.\n\nFor more information about using this template, including OpenShift considerations, see https://github.com/openshift/nodejs-ex/blob/master/README.md.", "labels": { - "template": "nodejs-mongo-persistent" + "template": "nodejs-mongo-persistent", + "app": "nodejs-mongo-persistent" }, "objects": [ { diff --git a/roles/openshift_examples/files/examples/v3.9/quickstart-templates/nodejs-mongodb.json b/roles/openshift_examples/files/examples/v3.9/quickstart-templates/nodejs-mongodb.json index b3afae46e..0ce36dba5 100644 --- a/roles/openshift_examples/files/examples/v3.9/quickstart-templates/nodejs-mongodb.json +++ b/roles/openshift_examples/files/examples/v3.9/quickstart-templates/nodejs-mongodb.json @@ -17,7 +17,8 @@ }, "message": "The following service(s) have been created in your project: ${NAME}, ${DATABASE_SERVICE_NAME}.\n\nFor more information about using this template, including OpenShift considerations, see https://github.com/openshift/nodejs-ex/blob/master/README.md.", "labels": { - "template": "nodejs-mongodb-example" + "template": "nodejs-mongodb-example", + "app": "nodejs-mongodb-example" }, "objects": [ { diff --git a/roles/openshift_examples/files/examples/v3.9/quickstart-templates/rails-postgresql-persistent.json b/roles/openshift_examples/files/examples/v3.9/quickstart-templates/rails-postgresql-persistent.json index 1c03be28a..10e9382cc 100644 --- a/roles/openshift_examples/files/examples/v3.9/quickstart-templates/rails-postgresql-persistent.json +++ b/roles/openshift_examples/files/examples/v3.9/quickstart-templates/rails-postgresql-persistent.json @@ -4,7 +4,7 @@ "metadata": { "name": "rails-pgsql-persistent", "annotations": { - "openshift.io/display-name": "Rails + PostgreSQL (Persistent)", + "openshift.io/display-name": "Rails + PostgreSQL", "description": "An example Rails application with a PostgreSQL database. For more information about using this template, including OpenShift considerations, see https://github.com/openshift/rails-ex/blob/master/README.md.", "tags": "quickstart,ruby,rails", "iconClass": "icon-ruby", @@ -17,7 +17,8 @@ }, "message": "The following service(s) have been created in your project: ${NAME}, ${DATABASE_SERVICE_NAME}.\n\nFor more information about using this template, including OpenShift considerations, see https://github.com/openshift/rails-ex/blob/master/README.md.", "labels": { - "template": "rails-pgsql-persistent" + "template": "rails-pgsql-persistent", + "app": "rails-pgsql-persistent" }, "objects": [ { diff --git a/roles/openshift_examples/files/examples/v3.9/quickstart-templates/rails-postgresql.json b/roles/openshift_examples/files/examples/v3.9/quickstart-templates/rails-postgresql.json index 240289d33..8ec2c8ea6 100644 --- a/roles/openshift_examples/files/examples/v3.9/quickstart-templates/rails-postgresql.json +++ b/roles/openshift_examples/files/examples/v3.9/quickstart-templates/rails-postgresql.json @@ -17,7 +17,8 @@ }, "message": "The following service(s) have been created in your project: ${NAME}, ${DATABASE_SERVICE_NAME}.\n\nFor more information about using this template, including OpenShift considerations, see https://github.com/openshift/rails-ex/blob/master/README.md.", "labels": { - "template": "rails-postgresql-example" + "template": "rails-postgresql-example", + "app": "rails-postgresql-example" }, "objects": [ { diff --git a/roles/openshift_examples/meta/main.yml b/roles/openshift_examples/meta/main.yml index 1a34c85fc..9f46a4683 100644 --- a/roles/openshift_examples/meta/main.yml +++ b/roles/openshift_examples/meta/main.yml @@ -13,3 +13,4 @@ galaxy_info: - cloud dependencies: - role: lib_utils +- role: openshift_facts diff --git a/roles/openshift_excluder/tasks/verify_excluder.yml b/roles/openshift_excluder/tasks/verify_excluder.yml index 4f5277fa2..22a3fcd3b 100644 --- a/roles/openshift_excluder/tasks/verify_excluder.yml +++ b/roles/openshift_excluder/tasks/verify_excluder.yml @@ -3,7 +3,7 @@ # - excluder - name: Get available excluder version repoquery: - name: "{{ excluder }}" + name: "{{ excluder }}{{ '-' ~ r_openshift_excluder_upgrade_target.split('.')[0:2] | join('.') ~ '*' if r_openshift_excluder_upgrade_target is defined else '' }}" ignore_excluders: true register: repoquery_out diff --git a/roles/openshift_expand_partition/tasks/main.yml b/roles/openshift_expand_partition/tasks/main.yml index 5ae863871..b38ebdfb4 100644 --- a/roles/openshift_expand_partition/tasks/main.yml +++ b/roles/openshift_expand_partition/tasks/main.yml @@ -8,7 +8,7 @@ - name: Determine if growpart is installed command: "rpm -q cloud-utils-growpart" register: has_growpart - failed_when: has_growpart.cr != 0 and 'package cloud-utils-growpart is not installed' not in has_growpart.stdout + failed_when: has_growpart.rc != 0 and 'package cloud-utils-growpart is not installed' not in has_growpart.stdout changed_when: false when: openshift_is_containerized | bool diff --git a/roles/openshift_facts/library/openshift_facts.py b/roles/openshift_facts/library/openshift_facts.py index d7c358a2f..26f0525e9 100755 --- a/roles/openshift_facts/library/openshift_facts.py +++ b/roles/openshift_facts/library/openshift_facts.py @@ -1465,6 +1465,11 @@ class OpenShiftFacts(object): if metadata: metadata['project']['attributes'].pop('sshKeys', None) metadata['instance'].pop('serviceAccounts', None) + elif bios_vendor == 'Amazon EC2': + # Adds support for Amazon EC2 C5 instance types + provider = 'aws' + metadata_url = 'http://169.254.169.254/latest/meta-data/' + metadata = get_provider_metadata(metadata_url) elif virt_type == 'xen' and virt_role == 'guest' and re.match(r'.*\.amazon$', product_version): provider = 'aws' metadata_url = 'http://169.254.169.254/latest/meta-data/' diff --git a/roles/openshift_grafana/defaults/main.yml b/roles/openshift_grafana/defaults/main.yml new file mode 100644 index 000000000..7fd7a085d --- /dev/null +++ b/roles/openshift_grafana/defaults/main.yml @@ -0,0 +1,12 @@ +--- +gf_body_tmp: + name: grafana_name + type: prometheus + typeLogoUrl: '' + access: proxy + url: prometheus_url + basicAuth: false + withCredentials: false + jsonData: + tlsSkipVerify: true + token: satoken diff --git a/roles/openshift_grafana/files/grafana-ocp-oauth.yml b/roles/openshift_grafana/files/grafana-ocp-oauth.yml new file mode 100644 index 000000000..82fa89004 --- /dev/null +++ b/roles/openshift_grafana/files/grafana-ocp-oauth.yml @@ -0,0 +1,661 @@ +--- +kind: Template +apiVersion: v1 +metadata: + name: grafana-ocp + annotations: + "openshift.io/display-name": Grafana ocp + description: | + Grafana server with patched Prometheus datasource. + iconClass: icon-cogs + tags: "metrics,monitoring,grafana,prometheus" +parameters: +- description: The location of the proxy image + name: IMAGE_GF + value: mrsiano/grafana-ocp:latest +- description: The location of the proxy image + name: IMAGE_PROXY + value: openshift/oauth-proxy:v1.0.0 +- description: External URL for the grafana route + name: ROUTE_URL + value: "" +- description: The namespace to instantiate heapster under. Defaults to 'grafana'. + name: NAMESPACE + value: grafana +- description: The session secret for the proxy + name: SESSION_SECRET + generate: expression + from: "[a-zA-Z0-9]{43}" +objects: +- apiVersion: v1 + kind: ServiceAccount + metadata: + name: grafana-ocp + namespace: "${NAMESPACE}" + annotations: + serviceaccounts.openshift.io/oauth-redirectreference.primary: '{"kind":"OAuthRedirectReference","apiVersion":"v1","reference":{"kind":"Route","name":"grafana-ocp"}}' +- apiVersion: authorization.openshift.io/v1 + kind: ClusterRoleBinding + metadata: + name: gf-cluster-reader + roleRef: + name: cluster-reader + subjects: + - kind: ServiceAccount + name: grafana-ocp + namespace: "${NAMESPACE}" +- apiVersion: route.openshift.io/v1 + kind: Route + metadata: + name: grafana-ocp + namespace: "${NAMESPACE}" + spec: + host: "${ROUTE_URL}" + to: + name: grafana-ocp + tls: + termination: Reencrypt +- apiVersion: v1 + kind: Service + metadata: + name: grafana-ocp + annotations: + prometheus.io/scrape: "true" + prometheus.io/scheme: https + service.alpha.openshift.io/serving-cert-secret-name: gf-tls + namespace: "${NAMESPACE}" + labels: + metrics-infra: grafana-ocp + name: grafana-ocp + spec: + ports: + - name: grafana-ocp + port: 443 + protocol: TCP + targetPort: 8443 + selector: + app: grafana-ocp +- apiVersion: v1 + kind: Secret + metadata: + name: gf-proxy + namespace: "${NAMESPACE}" + stringData: + session_secret: "${SESSION_SECRET}=" +# Deploy Prometheus behind an oauth proxy +- apiVersion: extensions/v1beta1 + kind: Deployment + metadata: + labels: + app: grafana-ocp + name: grafana-ocp + namespace: "${NAMESPACE}" + spec: + replicas: 1 + selector: + matchLabels: + app: grafana-ocp + template: + metadata: + labels: + app: grafana-ocp + name: grafana-ocp-app + spec: + serviceAccountName: grafana-ocp + containers: + - name: oauth-proxy + image: ${IMAGE_PROXY} + imagePullPolicy: IfNotPresent + ports: + - containerPort: 8443 + name: web + args: + - -https-address=:8443 + - -http-address= + - -email-domain=* + - -client-id=system:serviceaccount:${NAMESPACE}:grafana-ocp + - -upstream=http://localhost:3000 + - -provider=openshift +# - '-openshift-delegate-urls={"/api/datasources": {"resource": "namespace", "verb": "get", "resourceName": "grafana-ocp", "namespace": "${NAMESPACE}"}}' + - '-openshift-sar={"namespace": "${NAMESPACE}", "verb": "list", "resource": "services"}' + - -tls-cert=/etc/tls/private/tls.crt + - -tls-key=/etc/tls/private/tls.key + - -client-secret-file=/var/run/secrets/kubernetes.io/serviceaccount/token + - -cookie-secret-file=/etc/proxy/secrets/session_secret + - -skip-auth-regex=^/metrics,/api/datasources,/api/dashboards + volumeMounts: + - mountPath: /etc/tls/private + name: gf-tls + - mountPath: /etc/proxy/secrets + name: secrets + + - name: grafana-ocp + image: ${IMAGE_GF} + ports: + - name: grafana-http + containerPort: 3000 + volumeMounts: + - mountPath: "/root/go/src/github.com/grafana/grafana/data" + name: gf-data + - mountPath: "/root/go/src/github.com/grafana/grafana/conf" + name: gfconfig + - mountPath: /etc/tls/private + name: gf-tls + - mountPath: /etc/proxy/secrets + name: secrets + command: + - "./bin/grafana-server" + + volumes: + - name: gfconfig + configMap: + name: gf-config + - name: secrets + secret: + secretName: gf-proxy + - name: gf-tls + secret: + secretName: gf-tls + - emptyDir: {} + name: gf-data +- apiVersion: v1 + kind: ConfigMap + metadata: + name: gf-config + namespace: "${NAMESPACE}" + data: + defaults.ini: |- + ##################### Grafana Configuration Defaults ##################### + # + # Do not modify this file in grafana installs + # + + # possible values : production, development + app_mode = production + + # instance name, defaults to HOSTNAME environment variable value or hostname if HOSTNAME var is empty + instance_name = ${HOSTNAME} + + #################################### Paths ############################### + [paths] + # Path to where grafana can store temp files, sessions, and the sqlite3 db (if that is used) + # + data = data + # + # Directory where grafana can store logs + # + logs = data/log + # + # Directory where grafana will automatically scan and look for plugins + # + plugins = data/plugins + + #################################### Server ############################## + [server] + # Protocol (http, https, socket) + protocol = http + + # The ip address to bind to, empty will bind to all interfaces + http_addr = + + # The http port to use + http_port = 3000 + + # The public facing domain name used to access grafana from a browser + domain = localhost + + # Redirect to correct domain if host header does not match domain + # Prevents DNS rebinding attacks + enforce_domain = false + + # The full public facing url + root_url = %(protocol)s://%(domain)s:%(http_port)s/ + + # Log web requests + router_logging = false + + # the path relative working path + static_root_path = public + + # enable gzip + enable_gzip = false + + # https certs & key file + cert_file = /etc/tls/private/tls.crt + cert_key = /etc/tls/private/tls.key + + # Unix socket path + socket = /tmp/grafana.sock + + #################################### Database ############################ + [database] + # You can configure the database connection by specifying type, host, name, user and password + # as separate properties or as on string using the url property. + + # Either "mysql", "postgres" or "sqlite3", it's your choice + type = sqlite3 + host = 127.0.0.1:3306 + name = grafana + user = root + # If the password contains # or ; you have to wrap it with triple quotes. Ex """#password;""" + password = + # Use either URL or the previous fields to configure the database + # Example: mysql://user:secret@host:port/database + url = + + # Max idle conn setting default is 2 + max_idle_conn = 2 + + # Max conn setting default is 0 (mean not set) + max_open_conn = + + # For "postgres", use either "disable", "require" or "verify-full" + # For "mysql", use either "true", "false", or "skip-verify". + ssl_mode = disable + + ca_cert_path = + client_key_path = + client_cert_path = + server_cert_name = + + # For "sqlite3" only, path relative to data_path setting + path = grafana.db + + #################################### Session ############################# + [session] + # Either "memory", "file", "redis", "mysql", "postgres", "memcache", default is "file" + provider = file + + # Provider config options + # memory: not have any config yet + # file: session dir path, is relative to grafana data_path + # redis: config like redis server e.g. `addr=127.0.0.1:6379,pool_size=100,db=grafana` + # postgres: user=a password=b host=localhost port=5432 dbname=c sslmode=disable + # mysql: go-sql-driver/mysql dsn config string, examples: + # `user:password@tcp(127.0.0.1:3306)/database_name` + # `user:password@unix(/var/run/mysqld/mysqld.sock)/database_name` + # memcache: 127.0.0.1:11211 + + + provider_config = sessions + + # Session cookie name + cookie_name = grafana_sess + + # If you use session in https only, default is false + cookie_secure = false + + # Session life time, default is 86400 + session_life_time = 86400 + gc_interval_time = 86400 + + #################################### Data proxy ########################### + [dataproxy] + + # This enables data proxy logging, default is false + logging = false + + #################################### Analytics ########################### + [analytics] + # Server reporting, sends usage counters to stats.grafana.org every 24 hours. + # No ip addresses are being tracked, only simple counters to track + # running instances, dashboard and error counts. It is very helpful to us. + # Change this option to false to disable reporting. + reporting_enabled = true + + # Set to false to disable all checks to https://grafana.com + # for new versions (grafana itself and plugins), check is used + # in some UI views to notify that grafana or plugin update exists + # This option does not cause any auto updates, nor send any information + # only a GET request to https://grafana.com to get latest versions + check_for_updates = true + + # Google Analytics universal tracking code, only enabled if you specify an id here + google_analytics_ua_id = + + # Google Tag Manager ID, only enabled if you specify an id here + google_tag_manager_id = + + #################################### Security ############################ + [security] + # default admin user, created on startup + admin_user = admin + + # default admin password, can be changed before first start of grafana, or in profile settings + admin_password = admin + + # used for signing + secret_key = SW2YcwTIb9zpOOhoPsMm + + # Auto-login remember days + login_remember_days = 7 + cookie_username = grafana_user + cookie_remember_name = grafana_remember + + # disable gravatar profile images + disable_gravatar = false + + # data source proxy whitelist (ip_or_domain:port separated by spaces) + data_source_proxy_whitelist = + + [snapshots] + # snapshot sharing options + external_enabled = true + external_snapshot_url = https://snapshots-origin.raintank.io + external_snapshot_name = Publish to snapshot.raintank.io + + # remove expired snapshot + snapshot_remove_expired = true + + # remove snapshots after 90 days + snapshot_TTL_days = 90 + + #################################### Users #################################### + [users] + # disable user signup / registration + allow_sign_up = true + + # Allow non admin users to create organizations + allow_org_create = true + + # Set to true to automatically assign new users to the default organization (id 1) + auto_assign_org = true + + # Default role new users will be automatically assigned (if auto_assign_org above is set to true) + auto_assign_org_role = Admin + + # Require email validation before sign up completes + verify_email_enabled = false + + # Background text for the user field on the login page + login_hint = email or username + + # Default UI theme ("dark" or "light") + default_theme = dark + + # External user management + external_manage_link_url = + external_manage_link_name = + external_manage_info = + + [auth] + # Set to true to disable (hide) the login form, useful if you use OAuth + disable_login_form = true + + # Set to true to disable the signout link in the side menu. useful if you use auth.proxy + disable_signout_menu = true + + #################################### Anonymous Auth ###################### + [auth.anonymous] + # enable anonymous access + enabled = true + + # specify organization name that should be used for unauthenticated users + org_name = Main Org. + + # specify role for unauthenticated users + org_role = Admin + + #################################### Github Auth ######################### + [auth.github] + enabled = false + allow_sign_up = true + client_id = some_id + client_secret = some_secret + scopes = user:email + auth_url = https://github.com/login/oauth/authorize + token_url = https://github.com/login/oauth/access_token + api_url = https://api.github.com/user + team_ids = + allowed_organizations = + + #################################### Google Auth ######################### + [auth.google] + enabled = false + allow_sign_up = true + client_id = some_client_id + client_secret = some_client_secret + scopes = https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email + auth_url = https://accounts.google.com/o/oauth2/auth + token_url = https://accounts.google.com/o/oauth2/token + api_url = https://www.googleapis.com/oauth2/v1/userinfo + allowed_domains = + hosted_domain = + + #################################### Grafana.com Auth #################### + # legacy key names (so they work in env variables) + [auth.grafananet] + enabled = false + allow_sign_up = true + client_id = some_id + client_secret = some_secret + scopes = user:email + allowed_organizations = + + [auth.grafana_com] + enabled = false + allow_sign_up = true + client_id = some_id + client_secret = some_secret + scopes = user:email + allowed_organizations = + + #################################### Generic OAuth ####################### + [auth.generic_oauth] + name = OAuth + enabled = false + allow_sign_up = true + client_id = some_id + client_secret = some_secret + scopes = user:email + auth_url = + token_url = + api_url = + team_ids = + allowed_organizations = + + #################################### Basic Auth ########################## + [auth.basic] + enabled = false + + #################################### Auth Proxy ########################## + [auth.proxy] + enabled = true + header_name = X-WEBAUTH-USER + header_property = username + auto_sign_up = true + ldap_sync_ttl = 60 + whitelist = + + #################################### Auth LDAP ########################### + [auth.ldap] + enabled = false + config_file = /etc/grafana/ldap.toml + allow_sign_up = true + + #################################### SMTP / Emailing ##################### + [smtp] + enabled = false + host = localhost:25 + user = + # If the password contains # or ; you have to wrap it with trippel quotes. Ex """#password;""" + password = + cert_file = + key_file = + skip_verify = false + from_address = admin@grafana.localhost + from_name = Grafana + ehlo_identity = + + [emails] + welcome_email_on_sign_up = false + templates_pattern = emails/*.html + + #################################### Logging ########################## + [log] + # Either "console", "file", "syslog". Default is console and file + # Use space to separate multiple modes, e.g. "console file" + mode = console file + + # Either "debug", "info", "warn", "error", "critical", default is "info" + level = error + + # optional settings to set different levels for specific loggers. Ex filters = sqlstore:debug + filters = + + # For "console" mode only + [log.console] + level = + + # log line format, valid options are text, console and json + format = console + + # For "file" mode only + [log.file] + level = + + # log line format, valid options are text, console and json + format = text + + # This enables automated log rotate(switch of following options), default is true + log_rotate = true + + # Max line number of single file, default is 1000000 + max_lines = 1000000 + + # Max size shift of single file, default is 28 means 1 << 28, 256MB + max_size_shift = 28 + + # Segment log daily, default is true + daily_rotate = true + + # Expired days of log file(delete after max days), default is 7 + max_days = 7 + + [log.syslog] + level = + + # log line format, valid options are text, console and json + format = text + + # Syslog network type and address. This can be udp, tcp, or unix. If left blank, the default unix endpoints will be used. + network = + address = + + # Syslog facility. user, daemon and local0 through local7 are valid. + facility = + + # Syslog tag. By default, the process' argv[0] is used. + tag = + + + #################################### AMQP Event Publisher ################ + [event_publisher] + enabled = false + rabbitmq_url = amqp://localhost/ + exchange = grafana_events + + #################################### Dashboard JSON files ################ + [dashboards.json] + enabled = false + path = /var/lib/grafana/dashboards + + #################################### Usage Quotas ######################## + [quota] + enabled = false + + #### set quotas to -1 to make unlimited. #### + # limit number of users per Org. + org_user = 10 + + # limit number of dashboards per Org. + org_dashboard = 100 + + # limit number of data_sources per Org. + org_data_source = 10 + + # limit number of api_keys per Org. + org_api_key = 10 + + # limit number of orgs a user can create. + user_org = 10 + + # Global limit of users. + global_user = -1 + + # global limit of orgs. + global_org = -1 + + # global limit of dashboards + global_dashboard = -1 + + # global limit of api_keys + global_api_key = -1 + + # global limit on number of logged in users. + global_session = -1 + + #################################### Alerting ############################ + [alerting] + # Disable alerting engine & UI features + enabled = true + # Makes it possible to turn off alert rule execution but alerting UI is visible + execute_alerts = true + + #################################### Internal Grafana Metrics ############ + # Metrics available at HTTP API Url /api/metrics + [metrics] + enabled = true + interval_seconds = 10 + + # Send internal Grafana metrics to graphite + [metrics.graphite] + # Enable by setting the address setting (ex localhost:2003) + address = + prefix = prod.grafana.%(instance_name)s. + + [grafana_net] + url = https://grafana.com + + [grafana_com] + url = https://grafana.com + + #################################### Distributed tracing ############ + [tracing.jaeger] + # jaeger destination (ex localhost:6831) + address = + # tag that will always be included in when creating new spans. ex (tag1:value1,tag2:value2) + always_included_tag = + # Type specifies the type of the sampler: const, probabilistic, rateLimiting, or remote + sampler_type = const + # jaeger samplerconfig param + # for "const" sampler, 0 or 1 for always false/true respectively + # for "probabilistic" sampler, a probability between 0 and 1 + # for "rateLimiting" sampler, the number of spans per second + # for "remote" sampler, param is the same as for "probabilistic" + # and indicates the initial sampling rate before the actual one + # is received from the mothership + sampler_param = 1 + + #################################### External Image Storage ############## + [external_image_storage] + # You can choose between (s3, webdav, gcs) + provider = + + [external_image_storage.s3] + bucket_url = + bucket = + region = + path = + access_key = + secret_key = + + [external_image_storage.webdav] + url = + username = + password = + public_url = + + [external_image_storage.gcs] + key_file = + bucket = diff --git a/roles/openshift_grafana/files/grafana-ocp.yml b/roles/openshift_grafana/files/grafana-ocp.yml new file mode 100644 index 000000000..bc7b4b286 --- /dev/null +++ b/roles/openshift_grafana/files/grafana-ocp.yml @@ -0,0 +1,76 @@ +--- +kind: Template +apiVersion: v1 +metadata: + name: grafana-ocp + annotations: + "openshift.io/display-name": Grafana ocp + description: | + Grafana server with patched Prometheus datasource. + iconClass: icon-cogs + tags: "metrics,monitoring,grafana,prometheus" +parameters: +- description: External URL for the grafana route + name: ROUTE_URL + value: "" +- description: The namespace to instantiate heapster under. Defaults to 'grafana'. + name: NAMESPACE + value: grafana +objects: +- apiVersion: route.openshift.io/v1 + kind: Route + metadata: + name: grafana-ocp + namespace: "${NAMESPACE}" + spec: + host: "${ROUTE_URL}" + to: + name: grafana-ocp +- apiVersion: v1 + kind: Service + metadata: + name: grafana-ocp + namespace: "${NAMESPACE}" + labels: + metrics-infra: grafana-ocp + name: grafana-ocp + spec: + selector: + name: grafana-ocp + ports: + - port: 8082 + protocol: TCP + targetPort: grafana-http +- apiVersion: v1 + kind: ReplicationController + metadata: + name: grafana-ocp + namespace: "${NAMESPACE}" + labels: + metrics-infra: grafana-ocp + name: grafana-ocp + spec: + selector: + name: grafana-ocp + replicas: 1 + template: + version: v1 + metadata: + labels: + metrics-infra: grafana-ocp + name: grafana-ocp + spec: + volumes: + - name: data + emptyDir: {} + containers: + - image: "mrsiano/grafana-ocp:latest" + name: grafana-ocp + ports: + - name: grafana-http + containerPort: 3000 + volumeMounts: + - name: data + mountPath: "/root/go/src/github.com/grafana/grafana/data" + command: + - "./bin/grafana-server" diff --git a/roles/openshift_grafana/files/openshift-cluster-monitoring.json b/roles/openshift_grafana/files/openshift-cluster-monitoring.json new file mode 100644 index 000000000..f59ca997f --- /dev/null +++ b/roles/openshift_grafana/files/openshift-cluster-monitoring.json @@ -0,0 +1,5138 @@ +{ + "dashboard": { + "description": "Monitors Openshift cluster using Prometheus. Shows overall cluster CPU / Memory / Filesystem usage as well as individual pod, containers, systemd services statistics. Uses cAdvisor metrics only.", + "editable": true, + "gnetId": 315, + "graphTooltip": 0, + "hideControls": false, + "id": null, + "links": [], + "rows": [ + { + "collapse": false, + "height": "200px", + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "decimals": 2, + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "height": "200px", + "id": 32, + "legend": { + "alignAsTable": false, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": false, + "show": false, + "sideWidth": 200, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 12, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum (irate (container_network_receive_bytes_total{kubernetes_io_hostname=~\"^$Node$\"}[2m]))", + "format": "time_series", + "instant": false, + "interval": "1s", + "intervalFactor": 1, + "legendFormat": "Received", + "metric": "network", + "refId": "A", + "step": 1 + }, + { + "expr": "- sum (irate (container_network_transmit_bytes_total{kubernetes_io_hostname=~\"^$Node$\"}[2m]))", + "format": "time_series", + "interval": "1s", + "intervalFactor": 1, + "legendFormat": "Sent", + "metric": "network", + "refId": "B", + "step": 1 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Network I/O pressure", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 0, + "value_type": "cumulative" + }, + "transparent": false, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": false, + "title": "Network I/O pressure", + "titleSize": "h6" + }, + { + "collapse": false, + "height": "250px", + "panels": [ + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": true, + "colors": [ + "rgba(50, 172, 45, 0.97)", + "rgba(237, 129, 40, 0.89)", + "rgba(245, 54, 54, 0.9)" + ], + "datasource": "${DS_PR}", + "editable": true, + "error": false, + "format": "percent", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": true, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "height": "180px", + "id": 4, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "span": 4, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum (container_memory_working_set_bytes{id=\"/\",kubernetes_io_hostname=~\"^$Node$\"}) / sum (machine_memory_bytes{kubernetes_io_hostname=~\"^$Node$\"}) * 100", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "refId": "A", + "step": 20 + } + ], + "thresholds": "", + "title": "Cluster memory usage", + "transparent": false, + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": true, + "colors": [ + "rgba(50, 172, 45, 0.97)", + "rgba(237, 129, 40, 0.89)", + "rgba(245, 54, 54, 0.9)" + ], + "datasource": "${DS_PR}", + "decimals": 2, + "editable": true, + "error": false, + "format": "percent", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": true, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "height": "180px", + "id": 6, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "span": 4, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum (irate (container_cpu_usage_seconds_total{id=\"/\",kubernetes_io_hostname=~\"^$Node$\"}[2m])) / sum (machine_cpu_cores{kubernetes_io_hostname=~\"^$Node$\"}) * 100", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "refId": "A", + "step": 20 + } + ], + "thresholds": "", + "title": "Cluster CPU usage ", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": true, + "colors": [ + "rgba(50, 172, 45, 0.97)", + "rgba(237, 129, 40, 0.89)", + "rgba(245, 54, 54, 0.9)" + ], + "datasource": "${DS_PR}", + "decimals": 2, + "editable": true, + "error": false, + "format": "percent", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": true, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "height": "180px", + "id": 7, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "span": 4, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum (container_fs_usage_bytes{device=~\"^/dev/mapper/docker_.*\",id=\"/\",kubernetes_io_hostname=~\"^$Node$\"}) / sum (container_fs_limit_bytes{device=~\"^/dev/mapper/docker_.*\",id=\"/\",kubernetes_io_hostname=~\"^$Node$\"}) * 100", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "", + "metric": "", + "refId": "A", + "step": 20 + } + ], + "thresholds": "", + "title": "Cluster filesystem usage", + "type": "singlestat", + "valueFontSize": "80%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(50, 172, 45, 0.97)", + "rgba(237, 129, 40, 0.89)", + "rgba(245, 54, 54, 0.9)" + ], + "datasource": "${DS_PR}", + "decimals": 2, + "editable": true, + "error": false, + "format": "bytes", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "height": "1px", + "id": 9, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "20%", + "prefix": "", + "prefixFontSize": "20%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "span": 2, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum (container_memory_working_set_bytes{id=\"/\",kubernetes_io_hostname=~\"^$Node$\"})", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "refId": "A", + "step": 20 + } + ], + "thresholds": "", + "title": "Used", + "type": "singlestat", + "valueFontSize": "50%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(50, 172, 45, 0.97)", + "rgba(237, 129, 40, 0.89)", + "rgba(245, 54, 54, 0.9)" + ], + "datasource": "${DS_PR}", + "decimals": 2, + "editable": true, + "error": false, + "format": "bytes", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "height": "1px", + "id": 10, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "span": 2, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum (machine_memory_bytes{kubernetes_io_hostname=~\"^$Node$\"})", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "refId": "A", + "step": 20 + } + ], + "thresholds": "", + "title": "Total", + "type": "singlestat", + "valueFontSize": "50%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(50, 172, 45, 0.97)", + "rgba(237, 129, 40, 0.89)", + "rgba(245, 54, 54, 0.9)" + ], + "datasource": "${DS_PR}", + "decimals": 2, + "editable": true, + "error": false, + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "height": "1px", + "id": 11, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": " cores", + "postfixFontSize": "30%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "span": 2, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum (irate (container_cpu_usage_seconds_total{id=\"/\",kubernetes_io_hostname=~\"^$Node$\"}[2m]))", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "refId": "A", + "step": 20 + } + ], + "thresholds": "", + "title": "Used", + "type": "singlestat", + "valueFontSize": "50%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(50, 172, 45, 0.97)", + "rgba(237, 129, 40, 0.89)", + "rgba(245, 54, 54, 0.9)" + ], + "datasource": "${DS_PR}", + "decimals": 2, + "editable": true, + "error": false, + "format": "none", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "height": "1px", + "id": 12, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": " cores", + "postfixFontSize": "30%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "span": 2, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum (machine_cpu_cores{kubernetes_io_hostname=~\"^$Node$\"})", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "refId": "A", + "step": 20 + } + ], + "thresholds": "", + "title": "Total", + "type": "singlestat", + "valueFontSize": "50%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(50, 172, 45, 0.97)", + "rgba(237, 129, 40, 0.89)", + "rgba(245, 54, 54, 0.9)" + ], + "datasource": "${DS_PR}", + "decimals": 2, + "editable": true, + "error": false, + "format": "bytes", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "height": "1px", + "id": 13, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "span": 2, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum (container_fs_usage_bytes{device=~\"^/dev/mapper/docker_.*$\",id=\"/\",kubernetes_io_hostname=~\"^$Node$\"})", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "refId": "A", + "step": 20 + } + ], + "thresholds": "", + "title": "Used", + "type": "singlestat", + "valueFontSize": "50%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + }, + { + "cacheTimeout": null, + "colorBackground": false, + "colorValue": false, + "colors": [ + "rgba(50, 172, 45, 0.97)", + "rgba(237, 129, 40, 0.89)", + "rgba(245, 54, 54, 0.9)" + ], + "datasource": "${DS_PR}", + "decimals": 2, + "editable": true, + "error": false, + "format": "bytes", + "gauge": { + "maxValue": 100, + "minValue": 0, + "show": false, + "thresholdLabels": false, + "thresholdMarkers": true + }, + "height": "1px", + "id": 14, + "interval": null, + "links": [], + "mappingType": 1, + "mappingTypes": [ + { + "name": "value to text", + "value": 1 + }, + { + "name": "range to text", + "value": 2 + } + ], + "maxDataPoints": 100, + "nullPointMode": "connected", + "nullText": null, + "postfix": "", + "postfixFontSize": "50%", + "prefix": "", + "prefixFontSize": "50%", + "rangeMaps": [ + { + "from": "null", + "text": "N/A", + "to": "null" + } + ], + "span": 2, + "sparkline": { + "fillColor": "rgba(31, 118, 189, 0.18)", + "full": false, + "lineColor": "rgb(31, 120, 193)", + "show": false + }, + "tableColumn": "", + "targets": [ + { + "expr": "sum (container_fs_limit_bytes{device=~\"^/dev/mapper/docker_.*$\",id=\"/\",kubernetes_io_hostname=~\"^$Node$\"})", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "refId": "A", + "step": 20 + } + ], + "thresholds": "", + "title": "Total", + "type": "singlestat", + "valueFontSize": "50%", + "valueMaps": [ + { + "op": "=", + "text": "N/A", + "value": "null" + } + ], + "valueName": "current" + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": false, + "title": "Total usage", + "titleSize": "h6" + }, + { + "collapse": true, + "height": 250, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "fill": 1, + "id": 33, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": true, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 12, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum (irate (container_cpu_usage_seconds_total{id=\"/\",kubernetes_io_hostname=~\"^$Node$\"}[2m])) / sum (machine_cpu_cores{kubernetes_io_hostname=~\"^$Node$\"}) ", + "format": "time_series", + "hide": false, + "interval": "1s", + "intervalFactor": 1, + "legendFormat": "overall cpu usage", + "refId": "A", + "step": 1 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Cluster CPU Usage", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "percent", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": false, + "title": "Dashboard Row", + "titleSize": "h6" + }, + { + "collapse": true, + "height": "250px", + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "decimals": 3, + "editable": true, + "error": false, + "fill": 0, + "grid": {}, + "height": "", + "id": 17, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 12, + "stack": false, + "steppedLine": true, + "targets": [ + { + "expr": "sum (irate (container_cpu_usage_seconds_total{image!=\"\",name=~\"^k8s_.*\",kubernetes_io_hostname=~\"^$Node$\"}[2m])) by (pod_name) * 100", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{ pod_name }}", + "metric": "container_cpu", + "refId": "A", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Pods CPU usage ", + "tooltip": { + "msResolution": true, + "shared": true, + "sort": 2, + "value_type": "cumulative" + }, + "transparent": false, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "percent", + "label": "% Usage", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": false, + "title": "Pods CPU usage", + "titleSize": "h6" + }, + { + "collapse": true, + "height": "250px", + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "decimals": 3, + "editable": true, + "error": false, + "fill": 0, + "grid": {}, + "height": "", + "id": 24, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "hideEmpty": false, + "hideZero": false, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": null, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 12, + "stack": false, + "steppedLine": true, + "targets": [ + { + "expr": "sum (irate (container_cpu_usage_seconds_total{image!=\"\",name=~\"^k8s_.*\",container_name!=\"POD\",kubernetes_io_hostname=~\"^$Node$\"}[2m])) by (container_name, pod_name)", + "format": "time_series", + "hide": false, + "interval": "1s", + "intervalFactor": 1, + "legendFormat": "pod: {{ pod_name }} | {{ container_name }}", + "metric": "container_cpu", + "refId": "A", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Containers Cores Usage", + "tooltip": { + "msResolution": true, + "shared": true, + "sort": 2, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": "cores", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": false, + "title": "Containers CPU usage", + "titleSize": "h6" + }, + { + "collapse": true, + "height": "250px", + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "decimals": 3, + "editable": true, + "error": false, + "fill": 0, + "grid": {}, + "height": "", + "id": 23, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 12, + "stack": false, + "steppedLine": true, + "targets": [ + { + "expr": "sum (irate (container_cpu_usage_seconds_total{id!=\"/\",kubernetes_io_hostname=~\"^$Node$\"}[2m])) by (id)", + "format": "time_series", + "hide": false, + "interval": "1s", + "intervalFactor": 1, + "legendFormat": "{{ id }}", + "metric": "container_cpu", + "refId": "A", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "System services CPU usage ", + "tooltip": { + "msResolution": true, + "shared": true, + "sort": 2, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": "cores", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": false, + "title": "System services CPU usage", + "titleSize": "h6" + }, + { + "collapse": true, + "height": 411, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "decimals": 3, + "editable": true, + "error": false, + "fill": 0, + "grid": {}, + "id": 34, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 12, + "stack": false, + "steppedLine": true, + "targets": [ + { + "expr": "sum (irate (container_memory_usage_bytes{id!=\"/\",kubernetes_io_hostname=~\"^$Node$\"}[2m])) by (id)", + "format": "time_series", + "hide": false, + "interval": "1s", + "intervalFactor": 1, + "legendFormat": "{{ id }}", + "metric": "container_cpu", + "refId": "A", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "All processes Memory usage ", + "tooltip": { + "msResolution": true, + "shared": true, + "sort": 2, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": "cores", + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": false, + "title": "All processes CPU usage", + "titleSize": "h6" + }, + { + "collapse": true, + "height": "250px", + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "decimals": 2, + "editable": true, + "error": false, + "fill": 0, + "grid": {}, + "id": 25, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": 200, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 12, + "stack": false, + "steppedLine": true, + "targets": [ + { + "expr": "sum (container_memory_working_set_bytes{image!=\"\",name=~\"^k8s_.*\",kubernetes_io_hostname=~\"^$Node$\"}) by (pod_name)", + "format": "time_series", + "interval": "1s", + "intervalFactor": 1, + "legendFormat": "{{ pod_name }}", + "metric": "container_memory_usage:sort_desc", + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Pods memory usage", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 2, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": false, + "title": "Pods memory usage", + "titleSize": "h6" + }, + { + "collapse": true, + "height": "250px", + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "decimals": 2, + "editable": true, + "error": false, + "fill": 0, + "grid": {}, + "id": 26, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": 200, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 12, + "stack": false, + "steppedLine": true, + "targets": [ + { + "expr": "sum (container_memory_rss{systemd_service_name=\"\",kubernetes_io_hostname=~\"^$Node$\"}) by (systemd_service_name)", + "format": "time_series", + "hide": false, + "interval": "1s", + "intervalFactor": 1, + "legendFormat": "{{ systemd_service_name }}", + "metric": "container_memory_usage:sort_desc", + "refId": "B", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "System services memory usage", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 2, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": false, + "title": "System services memory usage", + "titleSize": "h6" + }, + { + "collapse": true, + "height": "250px", + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "decimals": 2, + "editable": true, + "error": false, + "fill": 0, + "grid": {}, + "id": 27, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": 200, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 12, + "stack": false, + "steppedLine": true, + "targets": [ + { + "expr": "sum (container_memory_working_set_bytes{image!=\"\",name=~\"^k8s_.*\",container_name!=\"POD\",kubernetes_io_hostname=~\"^$Node$\"}) by (container_name, pod_name)", + "format": "time_series", + "interval": "1s", + "intervalFactor": 1, + "legendFormat": "pod: {{ pod_name }} | {{ container_name }}", + "metric": "container_memory_usage:sort_desc", + "refId": "A", + "step": 10 + }, + { + "expr": "sum (container_memory_working_set_bytes{image!=\"\",name!~\"^k8s_.*\",kubernetes_io_hostname=~\"^$Node$\"}) by (kubernetes_io_hostname, name, image)", + "format": "time_series", + "hide": false, + "interval": "1s", + "intervalFactor": 1, + "legendFormat": "docker: {{ kubernetes_io_hostname }} | {{ image }} ({{ name }})", + "metric": "container_memory_usage:sort_desc", + "refId": "B", + "step": 10 + }, + { + "expr": "sum (container_memory_working_set_bytes{rkt_container_name!=\"\",kubernetes_io_hostname=~\"^$Node$\"}) by (kubernetes_io_hostname, rkt_container_name)", + "format": "time_series", + "hide": false, + "interval": "1s", + "intervalFactor": 1, + "legendFormat": "rkt: {{ kubernetes_io_hostname }} | {{ rkt_container_name }}", + "metric": "container_memory_usage:sort_desc", + "refId": "C", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Containers memory usage", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 2, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": false, + "title": "Containers memory usage", + "titleSize": "h6" + }, + { + "collapse": true, + "height": "500px", + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "decimals": 2, + "editable": true, + "error": false, + "fill": 0, + "grid": {}, + "id": 28, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": 200, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 12, + "stack": false, + "steppedLine": true, + "targets": [ + { + "expr": "sum (container_memory_working_set_bytes{id!=\"/\",kubernetes_io_hostname=~\"^$Node$\"}) by (id)", + "interval": "1s", + "intervalFactor": 1, + "legendFormat": "{{ id }}", + "metric": "container_memory_usage:sort_desc", + "refId": "A", + "step": 1 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "All processes memory usage", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 2, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "bytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": false, + "title": "All processes memory usage", + "titleSize": "h6" + }, + { + "collapse": true, + "height": "250px", + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "decimals": 2, + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "id": 30, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": 200, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 12, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum (irate (container_network_receive_bytes_total{image!=\"\",name=~\"^k8s_.*\",kubernetes_io_hostname=~\"^$Node$\"}[2m])) by (container_name, pod_name)", + "format": "time_series", + "hide": false, + "interval": "1s", + "intervalFactor": 1, + "legendFormat": "-> pod: {{ pod_name }} | {{ container_name }}", + "metric": "network", + "refId": "B", + "step": 1 + }, + { + "expr": "- sum (irate (container_network_transmit_bytes_total{image!=\"\",name=~\"^k8s_.*\",kubernetes_io_hostname=~\"^$Node$\"}[2m])) by (container_name, pod_name)", + "format": "time_series", + "hide": false, + "interval": "1s", + "intervalFactor": 1, + "legendFormat": "<- pod: {{ pod_name }} | {{ container_name }}", + "metric": "network", + "refId": "D", + "step": 1 + }, + { + "expr": "sum (irate (container_network_receive_bytes_total{image!=\"\",name!~\"^k8s_.*\",kubernetes_io_hostname=~\"^$Node$\"}[2m])) by (kubernetes_io_hostname, name, image)", + "format": "time_series", + "hide": false, + "interval": "1s", + "intervalFactor": 1, + "legendFormat": "-> docker: {{ kubernetes_io_hostname }} | {{ image }} ({{ name }})", + "metric": "network", + "refId": "A", + "step": 1 + }, + { + "expr": "- sum (irate (container_network_transmit_bytes_total{image!=\"\",name!~\"^k8s_.*\",kubernetes_io_hostname=~\"^$Node$\"}[2m])) by (kubernetes_io_hostname, name, image)", + "format": "time_series", + "hide": false, + "interval": "1s", + "intervalFactor": 1, + "legendFormat": "<- docker: {{ kubernetes_io_hostname }} | {{ image }} ({{ name }})", + "metric": "network", + "refId": "C", + "step": 1 + }, + { + "expr": "sum (irate (container_network_transmit_bytes_total{rkt_container_name!=\"\",kubernetes_io_hostname=~\"^$Node$\"}[2m])) by (kubernetes_io_hostname, rkt_container_name)", + "format": "time_series", + "hide": false, + "interval": "1s", + "intervalFactor": 1, + "legendFormat": "-> rkt: {{ kubernetes_io_hostname }} | {{ rkt_container_name }}", + "metric": "network", + "refId": "E", + "step": 1 + }, + { + "expr": "- sum (irate (container_network_transmit_bytes_total{rkt_container_name!=\"\",kubernetes_io_hostname=~\"^$Node$\"}[2m])) by (kubernetes_io_hostname, rkt_container_name)", + "format": "time_series", + "hide": false, + "interval": "1s", + "intervalFactor": 1, + "legendFormat": "<- rkt: {{ kubernetes_io_hostname }} | {{ rkt_container_name }}", + "metric": "network", + "refId": "F", + "step": 1 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Containers network I/O ", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 2, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": false, + "title": "Containers network I/O", + "titleSize": "h6" + }, + { + "collapse": true, + "height": 277, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "decimals": 2, + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "id": 16, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sideWidth": 200, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 12, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum (irate (container_network_receive_bytes_total{image!=\"\",name=~\"^k8s_.*\",kubernetes_io_hostname=~\"^$Node$\"}[2m])) by (pod_name)", + "format": "time_series", + "interval": "1s", + "intervalFactor": 1, + "legendFormat": "-> {{ pod_name }}", + "metric": "network", + "refId": "A", + "step": 1 + }, + { + "expr": "- sum (irate (container_network_transmit_bytes_total{image!=\"\",name=~\"^k8s_.*\",kubernetes_io_hostname=~\"^$Node$\"}[2m])) by (pod_name)", + "format": "time_series", + "interval": "1s", + "intervalFactor": 1, + "legendFormat": "<- {{ pod_name }}", + "metric": "network", + "refId": "B", + "step": 1 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Pods network I/O ", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 2, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": false, + "title": "Pods network I/O", + "titleSize": "h6" + }, + { + "collapse": true, + "height": "500px", + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "decimals": 2, + "editable": true, + "error": false, + "fill": 1, + "grid": {}, + "id": 29, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": false, + "show": true, + "sideWidth": 200, + "sort": "current", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 2, + "links": [], + "nullPointMode": "connected", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 12, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum (irate (container_network_receive_bytes_total{id!=\"/\",kubernetes_io_hostname=~\"^$Node$\"}[2m])) by (id)", + "format": "time_series", + "instant": true, + "interval": "1s", + "intervalFactor": 1, + "legendFormat": "-> {{ id }}", + "metric": "network", + "refId": "A", + "step": 1 + }, + { + "expr": "- sum (irate (container_network_transmit_bytes_total{id!=\"/\",kubernetes_io_hostname=~\"^$Node$\"}[2m])) by (id)", + "format": "time_series", + "interval": "1s", + "intervalFactor": 1, + "legendFormat": "<- {{ id }}", + "metric": "network", + "refId": "B", + "step": 1 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "All processes network I/O ", + "tooltip": { + "msResolution": false, + "shared": true, + "sort": 2, + "value_type": "cumulative" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "Bps", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": false + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": false, + "title": "All processes network I/O", + "titleSize": "h6" + }, + { + "collapse": true, + "height": 250, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "fill": 1, + "id": 35, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 12, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(openshift_build_total) by (phase,reason)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{ phase }} | {{ reason }}", + "refId": "A", + "step": 1 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "openshift_build_total", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "fill": 1, + "id": 54, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "count(openshift_build_active_time_seconds{phase=\"running\"} offset 10m)", + "format": "time_series", + "intervalFactor": 2, + "refId": "A", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Returns the number of builds that have been running for more than 10 minutes (600 seconds).", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "fill": 1, + "id": 55, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "count(openshift_build_active_time_seconds{phase=\"pending\"} offset 10m)", + "format": "time_series", + "intervalFactor": 2, + "refId": "A", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Returns the number of build that have been waiting at least 10 minutes (600 seconds) to start.", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "fill": 1, + "id": 56, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(openshift_build_total{phase=\"Failed\"})", + "format": "time_series", + "intervalFactor": 2, + "refId": "A", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Returns the number of failed builds, regardless of the failure reason.", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "fill": 1, + "id": 57, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "openshift_build_total{phase=\"Failed\",reason=\"FetchSourceFailed\"}", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{ instance }}", + "refId": "A", + "step": 1 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Returns the number of failed builds because of problems retrieving source from the associated Git repository.", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": true, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "fill": 1, + "id": 58, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": false, + "linewidth": 1, + "links": [], + "nullPointMode": "null as zero", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(openshift_build_total{phase=\"Complete\"})", + "format": "time_series", + "intervalFactor": 2, + "refId": "A", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Returns the number of successfully completed builds.", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "fill": 0, + "id": 59, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 1, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "openshift_build_total{phase=\"Failed\"} offset 5m", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{ reason }}", + "refId": "A", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Returns the failed builds totals, per failure reason, from 5 minutes ago.", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "OpenShift Builds", + "titleSize": "h6" + }, + { + "collapse": true, + "height": 250, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "fill": 1, + "id": 36, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(openshift_sdn_pod_setup_latency_sum)", + "format": "time_series", + "intervalFactor": 2, + "refId": "A", + "step": 1 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "openshift_sdn_pod_setup_latency_sum", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "fill": 1, + "id": 41, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(openshift_sdn_pod_teardown_latency{quantile=\"0.9\"}) by (instance)", + "format": "time_series", + "intervalFactor": 2, + "refId": "A", + "step": 1 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "openshift_sdn_pod_teardown_latency", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "fill": 1, + "id": 50, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "topk(10, (sum by (pod_name) (irate(container_network_receive_bytes_total{pod_name!=\"\"}[5m]))))", + "format": "time_series", + "interval": "", + "intervalFactor": 1, + "legendFormat": "{{ pod_name }}", + "refId": "A", + "step": 1 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Top 10 pods doing the most receive network traffic", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "decbytes", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "fill": 1, + "id": 37, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "openshift_sdn_pod_ips", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{ instance }} | {{ role }}", + "refId": "A", + "step": 1 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "openshift_sdn_pod_ips", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "fill": 1, + "id": 39, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "garbage_collector_monitoring_route:openshift:io_v1_rate_limiter_use", + "format": "time_series", + "intervalFactor": 2, + "refId": "A", + "step": 1 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "garbage_collector_monitoring_route:openshift:io_v1_rate_limiter_use", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "fill": 1, + "id": 42, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "openshift_sdn_arp_cache_entries", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{ role }} | {{ instance }}", + "refId": "A", + "step": 1 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "openshift_sdn_arp_cache_entries", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "fill": 1, + "id": 40, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "openshift_sdn_arp_cache_entries", + "format": "time_series", + "intervalFactor": 2, + "refId": "A", + "step": 1 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "openshift_sdn_arp_cache_entries", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "OpenShift SDN", + "titleSize": "h6" + }, + { + "collapse": true, + "height": 250, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "fill": 1, + "id": 44, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(kubelet_pleg_relist_latency_microseconds{kubernetes_io_hostname=~\"$Node\",quantile=\"0.9\"}[2m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{ role }} | {{ instance }}", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "kubelet_pleg_relist", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "µs", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "fill": 1, + "id": 51, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(kubelet_docker_operations_latency_microseconds{quantile=\"0.9\"}[2m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{ operation_type }}", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "kubelet_docker_operations_latency_microseconds{quantile=\"0.9\"}", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "µs", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "fill": 1, + "id": 52, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "kubelet_docker_operations_timeout", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{ operation_type }}", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Returns a running count (not a rate) of docker operations that have timed out since the kubelet was started.", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "fill": 1, + "id": 53, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "kubelet_docker_operations_errors", + "format": "time_series", + "intervalFactor": 1, + "legendFormat": "{{ operation_type }}", + "refId": "A", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Returns a running count (not a rate) of docker operations that have failed since the kubelet was started.", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Kubelet", + "titleSize": "h6" + }, + { + "collapse": true, + "height": 250, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "fill": 1, + "id": 46, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(scrape_samples_scraped[2m])", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "{{ kubernetes_name }} | {{ instance }} ", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "scrape_samples_scraped", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "fill": 1, + "id": 68, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sort_desc(sum without (cpu) (irate(container_cpu_usage_seconds_total{container_name=\"prometheus\"}[5m])))", + "format": "time_series", + "interval": "1s", + "intervalFactor": 1, + "refId": "A", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "CPU per instance of Prometheus container.", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Prometheus", + "titleSize": "h6" + }, + { + "collapse": true, + "height": 250, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "fill": 1, + "id": 48, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sort_desc(sum without (instance,type,client,contentType) (irate(apiserver_request_count{verb!~\"GET|LIST|WATCH\"}[2m]))) > 0", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{ resource }} || {{ verb }}", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Number of mutating API requests being made to the control plane.", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "fill": 1, + "id": 49, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sort_desc(sum without (instance,type,client,contentType) (irate(apiserver_request_count{verb=~\"GET|LIST|WATCH\"}[2m]))) > 0", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{ resource }} || {{ pod }}", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Number of non-mutating API requests being made to the control plane.", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "fill": 1, + "id": 74, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "endpoint_queue_latency", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": " quantile {{ quantile }}", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "endpoint_queue_latency", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "ms", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "API Server", + "titleSize": "h6" + }, + { + "collapse": true, + "height": 250, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "fill": 1, + "id": 61, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "etcd_disk_wal_fsync_duration_seconds_count", + "format": "time_series", + "intervalFactor": 2, + "refId": "A", + "step": 10 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "etcd_disk_wal_fsync_duration_seconds_count", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "etcd", + "titleSize": "h6" + }, + { + "collapse": true, + "height": 250, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "fill": 1, + "id": 62, + "legend": { + "alignAsTable": false, + "avg": false, + "current": false, + "max": false, + "min": false, + "rightSide": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 12, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(changes(container_start_time_seconds[10m]))", + "format": "time_series", + "intervalFactor": 2, + "refId": "A", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "The number of containers that start or restart over the last ten minutes.", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "Changes in your cluster", + "titleSize": "h6" + }, + { + "collapse": true, + "height": 250, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "fill": 1, + "id": 63, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(machine_cpu_cores)", + "format": "time_series", + "intervalFactor": 2, + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Total number of cores in the cluster.", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "fill": 1, + "id": 64, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(sort_desc(irate(container_cpu_usage_seconds_total{id=\"/\"}[5m])))", + "format": "time_series", + "intervalFactor": 2, + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Total number of consumed cores.", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "fill": 1, + "id": 65, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sort_desc(sum by (kubernetes_io_hostname,type) (irate(container_cpu_usage_seconds_total{id=\"/\"}[5m])))", + "format": "time_series", + "intervalFactor": 2, + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "CPU consumed per node in the cluster.", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "fill": 1, + "id": 66, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sort_desc(sum by (cpu,id,pod_name,container_name) (irate(container_cpu_usage_seconds_total{role=\"infra\"}[5m])))", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "CPU consumption per system service or container on the infrastructure nodes.", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "fill": 1, + "id": 67, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sort_desc(sum by (namespace) (irate(container_cpu_usage_seconds_total[5m])))", + "format": "time_series", + "intervalFactor": 2, + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "CPU consumed per namespace on the cluster.", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "fill": 1, + "id": 47, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(irate(container_cpu_usage_seconds_total{id=\"/\"}[3m])) / sum(machine_cpu_cores)", + "format": "time_series", + "intervalFactor": 2, + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Percentage of total cluster CPU in use", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "percent", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "fill": 1, + "id": 69, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum(container_memory_rss) / sum(machine_memory_bytes)", + "format": "time_series", + "intervalFactor": 2, + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Percentage of total cluster memory in use", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "percent", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "fill": 1, + "id": 70, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum by (kubernetes_io_hostname) (irate(container_cpu_usage_seconds_total{id=~\"/system.slice/(docker|etcd).service\"}[5m]))", + "format": "time_series", + "intervalFactor": 2, + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "Aggregate CPU usage (seconds total) of etcd+docker", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "System and container CPU", + "titleSize": "h6" + }, + { + "collapse": true, + "height": 250, + "panels": [ + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "fill": 1, + "id": 71, + "legend": { + "avg": false, + "current": false, + "max": false, + "min": false, + "show": false, + "total": false, + "values": false + }, + "lines": true, + "linewidth": 1, + "links": [ + { + "title": "Kubernetes Storage Metrics via Prometheus", + "type": "absolute", + "url": "https://docs.google.com/document/d/1Fh0T60T_y888LsRwC51CQHO75b2IZ3A34ZQS71s_F0g" + } + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "volumes_queue_latency", + "format": "time_series", + "intervalFactor": 2, + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "volumes_queue_latency", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "fill": 1, + "id": 72, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [ + { + "title": "Kubernetes Storage Metrics via Prometheus", + "type": "absolute", + "url": "https://docs.google.com/document/d/1Fh0T60T_y888LsRwC51CQHO75b2IZ3A34ZQS71s_F0g" + } + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "irate(cloudprovider_gce_api_request_duration_seconds_count[2m])", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{ request }}", + "refId": "A", + "step": 4 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "cloudprovider_aws_api_request_duration_seconds_count", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "none", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + }, + { + "aliasColors": {}, + "bars": false, + "dashLength": 10, + "dashes": false, + "datasource": "${DS_PR}", + "fill": 1, + "id": 73, + "legend": { + "alignAsTable": true, + "avg": true, + "current": true, + "max": false, + "min": false, + "rightSide": true, + "show": true, + "sort": "avg", + "sortDesc": true, + "total": false, + "values": true + }, + "lines": true, + "linewidth": 1, + "links": [ + { + "title": "Kubernetes Storage Metrics via Prometheus", + "type": "absolute", + "url": "https://docs.google.com/document/d/1Fh0T60T_y888LsRwC51CQHO75b2IZ3A34ZQS71s_F0g" + } + ], + "nullPointMode": "null", + "percentage": false, + "pointradius": 5, + "points": false, + "renderer": "flot", + "seriesOverrides": [], + "spaceLength": 10, + "span": 6, + "stack": false, + "steppedLine": false, + "targets": [ + { + "expr": "sum (irate(storage_operation_duration_seconds_sum{kubernetes_io_hostname=~\"$Node\"}[2m])) by (operation_name,kubernetes_io_hostname)", + "format": "time_series", + "interval": "1s", + "intervalFactor": 1, + "legendFormat": "{{ operation_name }} || {{ kubernetes_io_hostname }}", + "refId": "A", + "step": 2 + } + ], + "thresholds": [], + "timeFrom": null, + "timeShift": null, + "title": "storage_operation_duration_seconds_sum", + "tooltip": { + "shared": true, + "sort": 0, + "value_type": "individual" + }, + "type": "graph", + "xaxis": { + "buckets": null, + "mode": "time", + "name": null, + "show": true, + "values": [] + }, + "yaxes": [ + { + "format": "s", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + }, + { + "format": "short", + "label": null, + "logBase": 1, + "max": null, + "min": null, + "show": true + } + ] + } + ], + "repeat": null, + "repeatIteration": null, + "repeatRowId": null, + "showTitle": true, + "title": "OpenShift Volumes", + "titleSize": "h6" + } + ], + "schemaVersion": 14, + "style": "dark", + "tags": [ + "kubernetes", + "openshift" + ], + "templating": { + "list": [ + { + "allValue": ".*", + "current": {}, + "datasource": "${DS_PR}", + "hide": 0, + "includeAll": true, + "label": null, + "multi": false, + "name": "Node", + "options": [], + "query": "label_values(kubernetes_io_hostname)", + "refresh": 1, + "regex": "", + "sort": 0, + "tagValuesQuery": "", + "tags": [], + "tagsQuery": "", + "type": "query", + "useTags": false + } + ] + }, + "time": { + "from": "now-30m", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "1s", + "2m", + "20s", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "browser", + "title": "openshift cluster monitoring", + "version": 6 + } +} diff --git a/roles/openshift_grafana/meta/main.yml b/roles/openshift_grafana/meta/main.yml new file mode 100644 index 000000000..8dea6f197 --- /dev/null +++ b/roles/openshift_grafana/meta/main.yml @@ -0,0 +1,13 @@ +--- +galaxy_info: + author: Eldad Marciano + description: Setup grafana pod + company: Red Hat, Inc. + license: Apache License, Version 2.0 + min_ansible_version: 2.3 + platforms: + - name: EL + versions: + - 7 + categories: + - metrics diff --git a/roles/openshift_grafana/tasks/gf-permissions.yml b/roles/openshift_grafana/tasks/gf-permissions.yml new file mode 100644 index 000000000..9d3c741ee --- /dev/null +++ b/roles/openshift_grafana/tasks/gf-permissions.yml @@ -0,0 +1,12 @@ +--- +- name: Create gf user on htpasswd + command: htpasswd -c /etc/origin/master/htpasswd gfadmin + +- name: Make sure master config use HTPasswdPasswordIdentityProvider + command: "sed -ie 's|AllowAllPasswordIdentityProvider|HTPasswdPasswordIdentityProvider\n file: /etc/origin/master/htpasswd|' /etc/origin/master/master-config.yaml" + +- name: Grant permission for gfuser + command: oc adm policy add-cluster-role-to-user cluster-reader gfadmin + +- name: Restart mater api + command: systemctl restart atomic-openshift-master-api.service diff --git a/roles/openshift_grafana/tasks/main.yml b/roles/openshift_grafana/tasks/main.yml new file mode 100644 index 000000000..6a06d40a9 --- /dev/null +++ b/roles/openshift_grafana/tasks/main.yml @@ -0,0 +1,122 @@ +--- +- name: Create grafana namespace + oc_project: + state: present + name: grafana + +- name: Configure Grafana Permissions + include_tasks: tasks/gf-permissions.yml + when: gf_oauth | default(false) | bool == true + +# TODO: we should grab this yaml file from openshift/origin +- name: Templatize grafana yaml + template: src=grafana-ocp.yaml dest=/tmp/grafana-ocp.yaml + register: + cl_file: /tmp/grafana-ocp.yaml + when: gf_oauth | default(false) | bool == false + +# TODO: we should grab this yaml file from openshift/origin +- name: Templatize grafana yaml + template: src=grafana-ocp-oauth.yaml dest=/tmp/grafana-ocp-oauth.yaml + register: + cl_file: /tmp/grafana-ocp-oauth.yaml + when: gf_oauth | default(false) | bool == true + +- name: Process the grafana file + oc_process: + namespace: grafana + template_name: "{{ cl_file }}" + create: True + when: gf_oauth | default(false) | bool == true + +- name: Wait to grafana be running + command: oc rollout status deployment/grafana-ocp + +- name: oc adm policy add-role-to-user view -z grafana-ocp -n {{ gf_prometheus_namespace }} + oc_adm_policy_user: + user: grafana-ocp + resource_kind: cluster-role + resource_name: view + state: present + role_namespace: "{{ gf_prometheus_namespace }}" + +- name: Get grafana route + oc_obj: + kind: route + name: grafana + namespace: grafana + register: route + +- name: Get prometheus route + oc_obj: + kind: route + name: prometheus + namespace: "{{ gf_prometheus_namespace }}" + register: route + +- name: Get the prometheus SA + oc_serviceaccount_secret: + state: list + service_account: prometheus + namespace: "{{ gf_prometheus_namespace }}" + register: sa + +- name: Get the management SA bearer token + set_fact: + management_token: "{{ sa.results | oo_filter_sa_secrets }}" + +- name: Ensure the SA bearer token value is read + oc_secret: + state: list + name: "{{ management_token }}" + namespace: "{{ gf_prometheus_namespace }}" + no_log: True + register: sa_secret + +- name: Get the SA bearer token for prometheus + set_fact: + token: "{{ sa_secret.results.encoded.token }}" + +- name: Convert to json + var: + ds_json: "{{ gf_body_tmp }} | to_json }}" + +- name: Set protocol type + var: + protocol: "{{ 'https' if {{ gf_oauth }} == true else 'http' }}" + +- name: Add gf datasrouce + uri: + url: "{{ protocol }}://{{ route }}/api/datasources" + user: admin + password: admin + method: POST + body: "{{ ds_json | regex_replace('grafana_name', {{ gf_datasource_name }}) | regex_replace('prometheus_url', 'https://'{{ prometheus }} ) | regex_replace('satoken', {{ token }}) }}" + headers: + Content-Type: "Content-Type: application/json" + register: add_ds + +- name: Regex setup ds name + replace: + path: "{{ lookup('file', 'openshift-cluster-monitoring.json') }}" + regexp: '${DS_PR}' + replace: '{{ gf_datasource_name }}' + backup: yes + +- name: Add new dashboard + uri: + url: "{{ protocol }}://{{ route }}/api/dashboards/db" + user: admin + password: admin + method: POST + body: "{{ lookup('file', 'openshift-cluster-monitoring.json') }}" + headers: + Content-Type: "Content-Type: application/json" + register: add_ds + +- name: Regex json tear down + replace: + path: "{{ lookup('file', 'openshift-cluster-monitoring.json') }}" + regexp: '${DS_PR}' + replace: '{{ gf_datasource_name }}' + backup: yes diff --git a/roles/openshift_health_checker/callback_plugins/zz_failure_summary.py b/roles/openshift_health_checker/callback_plugins/zz_failure_summary.py index dcaf87eca..c83adb26d 100644 --- a/roles/openshift_health_checker/callback_plugins/zz_failure_summary.py +++ b/roles/openshift_health_checker/callback_plugins/zz_failure_summary.py @@ -175,6 +175,8 @@ def format_failure(failure): play = failure['play'] task = failure['task'] msg = failure['msg'] + if not isinstance(msg, string_types): + msg = str(msg) checks = failure['checks'] fields = ( (u'Hosts', host), diff --git a/roles/openshift_health_checker/openshift_checks/__init__.py b/roles/openshift_health_checker/openshift_checks/__init__.py index 83e551b5d..b9c41d1b4 100644 --- a/roles/openshift_health_checker/openshift_checks/__init__.py +++ b/roles/openshift_health_checker/openshift_checks/__init__.py @@ -5,6 +5,7 @@ Health checks for OpenShift clusters. import json import operator import os +import re import time import collections @@ -309,28 +310,38 @@ class OpenShiftCheck(object): name_list = name_list.split(',') return [name.strip() for name in name_list if name.strip()] - @staticmethod - def get_major_minor_version(openshift_image_tag): + def get_major_minor_version(self, openshift_image_tag=None): """Parse and return the deployed version of OpenShift as a tuple.""" - if openshift_image_tag and openshift_image_tag[0] == 'v': - openshift_image_tag = openshift_image_tag[1:] - # map major release versions across releases - # to a common major version - openshift_major_release_version = { - "1": "3", - } + version = openshift_image_tag or self.get_var("openshift_image_tag") + components = [int(component) for component in re.findall(r'\d+', version)] - components = openshift_image_tag.split(".") - if not components or len(components) < 2: + if len(components) < 2: msg = "An invalid version of OpenShift was found for this host: {}" - raise OpenShiftCheckException(msg.format(openshift_image_tag)) + raise OpenShiftCheckException(msg.format(version)) + + # map major release version across releases to OCP major version + components[0] = {1: 3}.get(components[0], components[0]) + + return tuple(int(x) for x in components[:2]) + + def get_required_version(self, name, version_map): + """Return the correct required version(s) for the current (or nearest) OpenShift version.""" + openshift_version = self.get_major_minor_version() + + earliest = min(version_map) + latest = max(version_map) + if openshift_version < earliest: + return version_map[earliest] + if openshift_version > latest: + return version_map[latest] - if components[0] in openshift_major_release_version: - components[0] = openshift_major_release_version[components[0]] + required_version = version_map.get(openshift_version) + if not required_version: + msg = "There is no recommended version of {} for the current version of OpenShift ({})" + raise OpenShiftCheckException(msg.format(name, ".".join(str(comp) for comp in openshift_version))) - components = tuple(int(x) for x in components[:2]) - return components + return required_version def find_ansible_mount(self, path): """Return the mount point for path from ansible_mounts.""" diff --git a/roles/openshift_health_checker/openshift_checks/disk_availability.py b/roles/openshift_health_checker/openshift_checks/disk_availability.py index 87e6146d4..6e30a8610 100644 --- a/roles/openshift_health_checker/openshift_checks/disk_availability.py +++ b/roles/openshift_health_checker/openshift_checks/disk_availability.py @@ -21,7 +21,7 @@ class DiskAvailability(OpenShiftCheck): 'oo_etcd_to_config': 20 * 10**9, }, # Used to copy client binaries into, - # see roles/openshift_cli/library/openshift_container_binary_sync.py. + # see roles/lib_utils/library/openshift_container_binary_sync.py. '/usr/local/bin': { 'oo_masters_to_config': 1 * 10**9, 'oo_nodes_to_config': 1 * 10**9, diff --git a/roles/openshift_health_checker/openshift_checks/docker_image_availability.py b/roles/openshift_health_checker/openshift_checks/docker_image_availability.py index 7afb8f730..d298fbab2 100644 --- a/roles/openshift_health_checker/openshift_checks/docker_image_availability.py +++ b/roles/openshift_health_checker/openshift_checks/docker_image_availability.py @@ -40,7 +40,7 @@ class DockerImageAvailability(DockerHostMixin, OpenShiftCheck): # to look for images available remotely without waiting to pull them. dependencies = ["python-docker-py", "skopeo"] # command for checking if remote registries have an image, without docker pull - skopeo_command = "timeout 10 skopeo inspect --tls-verify={tls} {creds} docker://{registry}/{image}" + skopeo_command = "{proxyvars} timeout 10 skopeo inspect --tls-verify={tls} {creds} docker://{registry}/{image}" skopeo_example_command = "skopeo inspect [--tls-verify=false] [--creds=<user>:<pass>] docker://<registry>/<image>" def __init__(self, *args, **kwargs): @@ -56,7 +56,7 @@ class DockerImageAvailability(DockerHostMixin, OpenShiftCheck): # ordered list of registries (according to inventory vars) that docker will try for unscoped images regs = self.ensure_list("openshift_docker_additional_registries") # currently one of these registries is added whether the user wants it or not. - deployment_type = self.get_var("openshift_deployment_type") + deployment_type = self.get_var("openshift_deployment_type", default="") if deployment_type == "origin" and "docker.io" not in regs: regs.append("docker.io") elif deployment_type == 'openshift-enterprise' and "registry.access.redhat.com" not in regs: @@ -76,11 +76,20 @@ class DockerImageAvailability(DockerHostMixin, OpenShiftCheck): if oreg_auth_user != '' and oreg_auth_password != '': oreg_auth_user = self.template_var(oreg_auth_user) oreg_auth_password = self.template_var(oreg_auth_password) - self.skopeo_command_creds = "--creds={}:{}".format(quote(oreg_auth_user), quote(oreg_auth_password)) + self.skopeo_command_creds = quote("--creds={}:{}".format(oreg_auth_user, oreg_auth_password)) # record whether we could reach a registry or not (and remember results) self.reachable_registries = {} + # take note of any proxy settings needed + proxies = [] + for var in ['http_proxy', 'https_proxy', 'no_proxy']: + # ansible vars are openshift_http_proxy, openshift_https_proxy, openshift_no_proxy + value = self.get_var("openshift_" + var, default=None) + if value: + proxies.append(var.upper() + "=" + quote(self.template_var(value))) + self.skopeo_proxy_vars = " ".join(proxies) + def is_active(self): """Skip hosts with unsupported deployment types.""" deployment_type = self.get_var("openshift_deployment_type") @@ -249,11 +258,18 @@ class DockerImageAvailability(DockerHostMixin, OpenShiftCheck): if not self.reachable_registries[registry]: continue # do not keep trying unreachable registries - args = dict(registry=registry, image=image) - args["tls"] = "false" if registry in self.registries["insecure"] else "true" - args["creds"] = self.skopeo_command_creds if registry == self.registries["oreg"] else "" + args = dict( + proxyvars=self.skopeo_proxy_vars, + tls="false" if registry in self.registries["insecure"] else "true", + creds=self.skopeo_command_creds if registry == self.registries["oreg"] else "", + registry=quote(registry), + image=quote(image), + ) - result = self.execute_module_with_retries("command", {"_raw_params": self.skopeo_command.format(**args)}) + result = self.execute_module_with_retries("command", { + "_uses_shell": True, + "_raw_params": self.skopeo_command.format(**args), + }) if result.get("rc", 0) == 0 and not result.get("failed"): return True if result.get("rc") == 124: # RC 124 == timed out; mark unreachable @@ -263,6 +279,10 @@ class DockerImageAvailability(DockerHostMixin, OpenShiftCheck): def connect_to_registry(self, registry): """Use ansible wait_for module to test connectivity from host to registry. Returns bool.""" + if self.skopeo_proxy_vars != "": + # assume we can't connect directly; just waive the test + return True + # test a simple TCP connection host, _, port = registry.partition(":") port = port or 443 diff --git a/roles/openshift_health_checker/openshift_checks/logging/elasticsearch.py b/roles/openshift_health_checker/openshift_checks/logging/elasticsearch.py index 986a01f38..7f8c6ebdc 100644 --- a/roles/openshift_health_checker/openshift_checks/logging/elasticsearch.py +++ b/roles/openshift_health_checker/openshift_checks/logging/elasticsearch.py @@ -170,7 +170,7 @@ class Elasticsearch(LoggingCheck): """ errors = [] for pod_name in pods_by_name.keys(): - df_cmd = 'exec {} -- df --output=ipcent,pcent /elasticsearch/persistent'.format(pod_name) + df_cmd = '-c elasticsearch exec {} -- df --output=ipcent,pcent /elasticsearch/persistent'.format(pod_name) disk_output = self.exec_oc(df_cmd, [], save_as_name='get_pv_diskspace.json') lines = disk_output.splitlines() # expecting one header looking like 'IUse% Use%' and one body line diff --git a/roles/openshift_health_checker/openshift_checks/logging/kibana.py b/roles/openshift_health_checker/openshift_checks/logging/kibana.py index 3b1cf8baa..16ec3a7f6 100644 --- a/roles/openshift_health_checker/openshift_checks/logging/kibana.py +++ b/roles/openshift_health_checker/openshift_checks/logging/kibana.py @@ -5,12 +5,11 @@ Module for performing checks on a Kibana logging deployment import json import ssl -try: - from urllib2 import HTTPError, URLError - import urllib2 -except ImportError: - from urllib.error import HTTPError, URLError - import urllib.request as urllib2 +# pylint can't find the package when its installed in virtualenv +# pylint: disable=import-error,no-name-in-module +from ansible.module_utils.six.moves.urllib import request +# pylint: disable=import-error,no-name-in-module +from ansible.module_utils.six.moves.urllib.error import HTTPError, URLError from openshift_checks.logging.logging import LoggingCheck, OpenShiftCheckException @@ -65,7 +64,7 @@ class Kibana(LoggingCheck): # Verify that the url is returning a valid response try: # We only care if the url connects and responds - return_code = urllib2.urlopen(url, context=ctx).getcode() + return_code = request.urlopen(url, context=ctx).getcode() except HTTPError as httperr: return httperr.reason except URLError as urlerr: diff --git a/roles/openshift_health_checker/openshift_checks/ovs_version.py b/roles/openshift_health_checker/openshift_checks/ovs_version.py index 0cad19842..58a2692bd 100644 --- a/roles/openshift_health_checker/openshift_checks/ovs_version.py +++ b/roles/openshift_health_checker/openshift_checks/ovs_version.py @@ -3,7 +3,7 @@ Ansible module for determining if an installed version of Open vSwitch is incomp currently installed version of OpenShift. """ -from openshift_checks import OpenShiftCheck, OpenShiftCheckException +from openshift_checks import OpenShiftCheck from openshift_checks.mixins import NotContainerizedMixin @@ -16,10 +16,12 @@ class OvsVersion(NotContainerizedMixin, OpenShiftCheck): tags = ["health"] openshift_to_ovs_version = { - "3.7": ["2.6", "2.7", "2.8"], - "3.6": ["2.6", "2.7", "2.8"], - "3.5": ["2.6", "2.7"], - "3.4": "2.4", + (3, 4): "2.4", + (3, 5): ["2.6", "2.7"], + (3, 6): ["2.6", "2.7", "2.8"], + (3, 7): ["2.6", "2.7", "2.8"], + (3, 8): ["2.6", "2.7", "2.8"], + (3, 9): ["2.6", "2.7", "2.8"], } def is_active(self): @@ -40,16 +42,5 @@ class OvsVersion(NotContainerizedMixin, OpenShiftCheck): return self.execute_module("rpm_version", args) def get_required_ovs_version(self): - """Return the correct Open vSwitch version for the current OpenShift version""" - openshift_version_tuple = self.get_major_minor_version(self.get_var("openshift_image_tag")) - - if openshift_version_tuple < (3, 5): - return self.openshift_to_ovs_version["3.4"] - - openshift_version = ".".join(str(x) for x in openshift_version_tuple) - ovs_version = self.openshift_to_ovs_version.get(openshift_version) - if ovs_version: - return self.openshift_to_ovs_version[openshift_version] - - msg = "There is no recommended version of Open vSwitch for the current version of OpenShift: {}" - raise OpenShiftCheckException(msg.format(openshift_version)) + """Return the correct Open vSwitch version(s) for the current OpenShift version.""" + return self.get_required_version("Open vSwitch", self.openshift_to_ovs_version) diff --git a/roles/openshift_health_checker/openshift_checks/package_version.py b/roles/openshift_health_checker/openshift_checks/package_version.py index f3a628e28..28aee8b35 100644 --- a/roles/openshift_health_checker/openshift_checks/package_version.py +++ b/roles/openshift_health_checker/openshift_checks/package_version.py @@ -1,8 +1,6 @@ """Check that available RPM packages match the required versions.""" -import re - -from openshift_checks import OpenShiftCheck, OpenShiftCheckException +from openshift_checks import OpenShiftCheck from openshift_checks.mixins import NotContainerizedMixin @@ -18,6 +16,8 @@ class PackageVersion(NotContainerizedMixin, OpenShiftCheck): (3, 5): ["2.6", "2.7"], (3, 6): ["2.6", "2.7", "2.8"], (3, 7): ["2.6", "2.7", "2.8"], + (3, 8): ["2.6", "2.7", "2.8"], + (3, 9): ["2.6", "2.7", "2.8"], } openshift_to_docker_version = { @@ -27,11 +27,9 @@ class PackageVersion(NotContainerizedMixin, OpenShiftCheck): (3, 4): "1.12", (3, 5): "1.12", (3, 6): "1.12", - } - - # map major OpenShift release versions across releases to a common major version - map_major_release_version = { - 1: 3, + (3, 7): "1.12", + (3, 8): "1.12", + (3, 9): ["1.12", "1.13"], } def is_active(self): @@ -83,48 +81,8 @@ class PackageVersion(NotContainerizedMixin, OpenShiftCheck): def get_required_ovs_version(self): """Return the correct Open vSwitch version(s) for the current OpenShift version.""" - openshift_version = self.get_openshift_version_tuple() - - earliest = min(self.openshift_to_ovs_version) - latest = max(self.openshift_to_ovs_version) - if openshift_version < earliest: - return self.openshift_to_ovs_version[earliest] - if openshift_version > latest: - return self.openshift_to_ovs_version[latest] - - ovs_version = self.openshift_to_ovs_version.get(openshift_version) - if not ovs_version: - msg = "There is no recommended version of Open vSwitch for the current version of OpenShift: {}" - raise OpenShiftCheckException(msg.format(".".join(str(comp) for comp in openshift_version))) - - return ovs_version + return self.get_required_version("Open vSwitch", self.openshift_to_ovs_version) def get_required_docker_version(self): """Return the correct Docker version(s) for the current OpenShift version.""" - openshift_version = self.get_openshift_version_tuple() - - earliest = min(self.openshift_to_docker_version) - latest = max(self.openshift_to_docker_version) - if openshift_version < earliest: - return self.openshift_to_docker_version[earliest] - if openshift_version > latest: - return self.openshift_to_docker_version[latest] - - docker_version = self.openshift_to_docker_version.get(openshift_version) - if not docker_version: - msg = "There is no recommended version of Docker for the current version of OpenShift: {}" - raise OpenShiftCheckException(msg.format(".".join(str(comp) for comp in openshift_version))) - - return docker_version - - def get_openshift_version_tuple(self): - """Return received image tag as a normalized (X, Y) minor version tuple.""" - version = self.get_var("openshift_image_tag") - comps = [int(component) for component in re.findall(r'\d+', version)] - - if len(comps) < 2: - msg = "An invalid version of OpenShift was found for this host: {}" - raise OpenShiftCheckException(msg.format(version)) - - comps[0] = self.map_major_release_version.get(comps[0], comps[0]) - return tuple(comps[0:2]) + return self.get_required_version("Docker", self.openshift_to_docker_version) diff --git a/roles/openshift_health_checker/test/kibana_test.py b/roles/openshift_health_checker/test/kibana_test.py index 04a5e89c4..750d4b9e9 100644 --- a/roles/openshift_health_checker/test/kibana_test.py +++ b/roles/openshift_health_checker/test/kibana_test.py @@ -1,12 +1,10 @@ import pytest import json -try: - import urllib2 - from urllib2 import HTTPError, URLError -except ImportError: - from urllib.error import HTTPError, URLError - import urllib.request as urllib2 +# pylint can't find the package when its installed in virtualenv +from ansible.module_utils.six.moves.urllib import request # pylint: disable=import-error +# pylint: disable=import-error +from ansible.module_utils.six.moves.urllib.error import HTTPError, URLError from openshift_checks.logging.kibana import Kibana, OpenShiftCheckException @@ -202,7 +200,7 @@ def test_verify_url_external_failure(lib_result, expect, monkeypatch): if type(lib_result) is int: return _http_return(lib_result) raise lib_result - monkeypatch.setattr(urllib2, 'urlopen', urlopen) + monkeypatch.setattr(request, 'urlopen', urlopen) check = Kibana() check._get_kibana_url = lambda: 'url' diff --git a/roles/openshift_health_checker/test/ovs_version_test.py b/roles/openshift_health_checker/test/ovs_version_test.py index 0238f49d5..80c7a0541 100644 --- a/roles/openshift_health_checker/test/ovs_version_test.py +++ b/roles/openshift_health_checker/test/ovs_version_test.py @@ -1,26 +1,7 @@ import pytest -from openshift_checks.ovs_version import OvsVersion, OpenShiftCheckException - - -def test_openshift_version_not_supported(): - def execute_module(*_): - return {} - - openshift_release = '111.7.0' - - task_vars = dict( - openshift=dict(common=dict()), - openshift_release=openshift_release, - openshift_image_tag='v' + openshift_release, - openshift_deployment_type='origin', - openshift_service_type='origin' - ) - - with pytest.raises(OpenShiftCheckException) as excinfo: - OvsVersion(execute_module, task_vars).run() - - assert "no recommended version of Open vSwitch" in str(excinfo.value) +from openshift_checks.ovs_version import OvsVersion +from openshift_checks import OpenShiftCheckException def test_invalid_openshift_release_format(): diff --git a/roles/openshift_health_checker/test/package_version_test.py b/roles/openshift_health_checker/test/package_version_test.py index d2916f617..868b4bd12 100644 --- a/roles/openshift_health_checker/test/package_version_test.py +++ b/roles/openshift_health_checker/test/package_version_test.py @@ -1,6 +1,7 @@ import pytest -from openshift_checks.package_version import PackageVersion, OpenShiftCheckException +from openshift_checks.package_version import PackageVersion +from openshift_checks import OpenShiftCheckException def task_vars_for(openshift_release, deployment_type): @@ -18,7 +19,7 @@ def task_vars_for(openshift_release, deployment_type): def test_openshift_version_not_supported(): check = PackageVersion(None, task_vars_for("1.2.3", 'origin')) - check.get_openshift_version_tuple = lambda: (3, 4, 1) # won't be in the dict + check.get_major_minor_version = lambda: (3, 4, 1) # won't be in the dict with pytest.raises(OpenShiftCheckException) as excinfo: check.get_required_ovs_version() diff --git a/roles/openshift_hosted/defaults/main.yml b/roles/openshift_hosted/defaults/main.yml index b6501d288..f40085976 100644 --- a/roles/openshift_hosted/defaults/main.yml +++ b/roles/openshift_hosted/defaults/main.yml @@ -69,7 +69,7 @@ r_openshift_hosted_router_os_firewall_allow: [] ############ openshift_hosted_registry_selector: "{{ openshift_registry_selector | default(openshift_hosted_infra_selector) }}" -penshift_hosted_registry_registryurl: "{{ openshift_hosted_images_dict[openshift_deployment_type] }}" +openshift_hosted_registry_registryurl: "{{ openshift_hosted_images_dict[openshift_deployment_type] }}" openshift_hosted_registry_routecertificates: {} openshift_hosted_registry_routetermination: "passthrough" diff --git a/roles/openshift_hosted/tasks/router.yml b/roles/openshift_hosted/tasks/router.yml index 2dc9c98f6..c2be00d19 100644 --- a/roles/openshift_hosted/tasks/router.yml +++ b/roles/openshift_hosted/tasks/router.yml @@ -18,6 +18,7 @@ - name: set_fact replicas set_fact: + # get_router_replicas is a custom filter in role lib_utils replicas: "{{ openshift_hosted_router_replicas | default(None) | get_router_replicas(router_nodes) }}" - name: Get the certificate contents for router diff --git a/roles/openshift_hosted/tasks/storage/glusterfs_endpoints.yml b/roles/openshift_hosted/tasks/storage/glusterfs_endpoints.yml index 77f020357..fef945d51 100644 --- a/roles/openshift_hosted/tasks/storage/glusterfs_endpoints.yml +++ b/roles/openshift_hosted/tasks/storage/glusterfs_endpoints.yml @@ -1,4 +1,10 @@ --- +- name: Create temp directory for doing work in + command: mktemp -d /tmp/openshift-hosted-ansible-XXXXXX + register: mktempHosted + changed_when: False + check_mode: no + - name: Generate GlusterFS registry endpoints template: src: "{{ openshift.common.examples_content_version }}/glusterfs-registry-endpoints.yml.j2" @@ -14,3 +20,10 @@ with_items: - "{{ mktempHosted.stdout }}/glusterfs-registry-service.yml" - "{{ mktempHosted.stdout }}/glusterfs-registry-endpoints.yml" + +- name: Delete temp directory + file: + name: "{{ mktempHosted.stdout }}" + state: absent + changed_when: False + check_mode: no diff --git a/roles/openshift_hosted_templates/files/v3.6/enterprise/registry-console.yaml b/roles/openshift_hosted_templates/files/v3.6/enterprise/registry-console.yaml index cc3159a32..0786e2d2f 100644 --- a/roles/openshift_hosted_templates/files/v3.6/enterprise/registry-console.yaml +++ b/roles/openshift_hosted_templates/files/v3.6/enterprise/registry-console.yaml @@ -102,7 +102,7 @@ objects: parameters: - description: 'Specify "registry/repository" prefix for container image; e.g. for "registry.access.redhat.com/openshift3/registry-console:latest", set prefix "registry.access.redhat.com/openshift3/"' name: IMAGE_PREFIX - value: "openshift3/" + value: "registry.access.redhat.com/openshift3/" - description: 'Specify component name for container image; e.g. for "registry.access.redhat.com/openshift3/registry-console:latest", use base name "registry-console"' name: IMAGE_BASENAME value: "registry-console" diff --git a/roles/openshift_hosted_templates/files/v3.7/enterprise/registry-console.yaml b/roles/openshift_hosted_templates/files/v3.7/enterprise/registry-console.yaml index 9f2e6125d..ccea54aaf 100644 --- a/roles/openshift_hosted_templates/files/v3.7/enterprise/registry-console.yaml +++ b/roles/openshift_hosted_templates/files/v3.7/enterprise/registry-console.yaml @@ -102,7 +102,7 @@ objects: parameters: - description: 'Specify "registry/repository" prefix for container image; e.g. for "registry.access.redhat.com/openshift3/registry-console:latest", set prefix "registry.access.redhat.com/openshift3/"' name: IMAGE_PREFIX - value: "openshift3/" + value: "registry.access.redhat.com/openshift3/" - description: 'Specify component name for container image; e.g. for "registry.access.redhat.com/openshift3/registry-console:latest", use base name "registry-console"' name: IMAGE_BASENAME value: "registry-console" diff --git a/roles/openshift_hosted_templates/files/v3.8/enterprise/registry-console.yaml b/roles/openshift_hosted_templates/files/v3.8/enterprise/registry-console.yaml index f04ce06d3..15ad4e9af 100644 --- a/roles/openshift_hosted_templates/files/v3.8/enterprise/registry-console.yaml +++ b/roles/openshift_hosted_templates/files/v3.8/enterprise/registry-console.yaml @@ -102,7 +102,7 @@ objects: parameters: - description: 'Specify "registry/repository" prefix for container image; e.g. for "registry.access.redhat.com/openshift3/registry-console:latest", set prefix "registry.access.redhat.com/openshift3/"' name: IMAGE_PREFIX - value: "openshift3/" + value: "registry.access.redhat.com/openshift3/" - description: 'Specify component name for container image; e.g. for "registry.access.redhat.com/openshift3/registry-console:latest", use base name "registry-console"' name: IMAGE_BASENAME value: "registry-console" diff --git a/roles/openshift_hosted_templates/files/v3.9/enterprise/registry-console.yaml b/roles/openshift_hosted_templates/files/v3.9/enterprise/registry-console.yaml index c178cf432..7acefa0f0 100644 --- a/roles/openshift_hosted_templates/files/v3.9/enterprise/registry-console.yaml +++ b/roles/openshift_hosted_templates/files/v3.9/enterprise/registry-console.yaml @@ -102,7 +102,7 @@ objects: parameters: - description: 'Specify "registry/repository" prefix for container image; e.g. for "registry.access.redhat.com/openshift3/registry-console:latest", set prefix "registry.access.redhat.com/openshift3/"' name: IMAGE_PREFIX - value: "openshift3/" + value: "registry.access.redhat.com/openshift3/" - description: 'Specify component name for container image; e.g. for "registry.access.redhat.com/openshift3/registry-console:latest", use base name "registry-console"' name: IMAGE_BASENAME value: "registry-console" diff --git a/roles/openshift_logging/README.md b/roles/openshift_logging/README.md index 27cfc17d6..a192bd67e 100644 --- a/roles/openshift_logging/README.md +++ b/roles/openshift_logging/README.md @@ -177,6 +177,9 @@ Elasticsearch OPS too, if using an OPS cluster: 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_external_address`: The IP address that mux will listen + on for connections from *external* clients. Default is the default ipv4 + interface as reported by the `ansible_default_ipv4` fact. - `openshift_logging_mux_cpu_request`: 100m - `openshift_logging_mux_memory_limit`: 512Mi - `openshift_logging_mux_default_namespaces`: Default `["mux-undefined"]` - the diff --git a/roles/openshift_logging/filter_plugins/openshift_logging.py b/roles/openshift_logging/filter_plugins/openshift_logging.py index ba412b5a6..247c7e4df 100644 --- a/roles/openshift_logging/filter_plugins/openshift_logging.py +++ b/roles/openshift_logging/filter_plugins/openshift_logging.py @@ -79,14 +79,6 @@ def entry_from_named_pair(register_pairs, key): 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] @@ -134,7 +126,6 @@ class FilterModule(object): return { 'random_word': random_word, 'entry_from_named_pair': entry_from_named_pair, - 'map_from_pairs': map_from_pairs, 'min_cpu': min_cpu, 'es_storage': es_storage, 'serviceaccount_name': serviceaccount_name, diff --git a/roles/openshift_logging/library/openshift_logging_facts.py b/roles/openshift_logging/library/openshift_logging_facts.py index 302a9b4c9..37ffb0204 100644 --- a/roles/openshift_logging/library/openshift_logging_facts.py +++ b/roles/openshift_logging/library/openshift_logging_facts.py @@ -276,7 +276,7 @@ class OpenshiftLoggingFacts(OCBaseCommand): return for item in role["subjects"]: comp = self.comp(item["name"]) - if comp is not None and namespace == item["namespace"]: + if comp is not None and namespace == item.get("namespace"): self.add_facts_for(comp, "clusterrolebindings", "cluster-readers", dict()) # this needs to end up nested under the service account... @@ -288,7 +288,7 @@ class OpenshiftLoggingFacts(OCBaseCommand): return for item in role["subjects"]: comp = self.comp(item["name"]) - if comp is not None and namespace == item["namespace"]: + if comp is not None and namespace == item.get("namespace"): self.add_facts_for(comp, "rolebindings", "logging-elasticsearch-view-role", dict()) # pylint: disable=no-self-use, too-many-return-statements diff --git a/roles/openshift_logging/tasks/annotate_ops_projects.yaml b/roles/openshift_logging/tasks/annotate_ops_projects.yaml index 4a2ee64f0..6fdba6580 100644 --- a/roles/openshift_logging/tasks/annotate_ops_projects.yaml +++ b/roles/openshift_logging/tasks/annotate_ops_projects.yaml @@ -12,6 +12,7 @@ separator: '#' content: metadata#annotations#openshift.io/logging.ui.hostname: "{{ openshift_logging_kibana_ops_hostname }}" + metadata#annotations#openshift.io/logging.data.prefix: ".operations" with_items: "{{ __logging_ops_projects.stdout.split(' ') }}" loop_control: loop_var: project diff --git a/roles/openshift_logging/tasks/delete_logging.yaml b/roles/openshift_logging/tasks/delete_logging.yaml index fbc3e3fd1..ced7397b5 100644 --- a/roles/openshift_logging/tasks/delete_logging.yaml +++ b/roles/openshift_logging/tasks/delete_logging.yaml @@ -131,13 +131,13 @@ when: not openshift_logging_install_eventrouter | default(false) | bool -# Update asset config in openshift-web-console namespace -- name: Remove Kibana route information from web console asset config +# Update console config in openshift-web-console namespace +- name: Remove Kibana route information from the web console config include_role: name: openshift_web_console - tasks_from: update_asset_config.yml + tasks_from: update_console_config.yml vars: - asset_config_edits: - - key: loggingPublicURL + console_config_edits: + - key: clusterInfo#loggingPublicURL value: "" when: openshift_web_console_install | default(true) | bool diff --git a/roles/openshift_logging/tasks/generate_certs.yaml b/roles/openshift_logging/tasks/generate_certs.yaml index 0d7f8c056..a40449bf6 100644 --- a/roles/openshift_logging/tasks/generate_certs.yaml +++ b/roles/openshift_logging/tasks/generate_certs.yaml @@ -19,7 +19,7 @@ command: > {{ openshift_client_binary }} adm --config={{ mktemp.stdout }}/admin.kubeconfig ca create-signer-cert --key={{generated_certs_dir}}/ca.key --cert={{generated_certs_dir}}/ca.crt - --serial={{generated_certs_dir}}/ca.serial.txt --name=logging-signer-test + --serial={{generated_certs_dir}}/ca.serial.txt --name=logging-signer-test --overwrite=false check_mode: no when: - not ca_key_file.stat.exists diff --git a/roles/openshift_logging/tasks/install_logging.yaml b/roles/openshift_logging/tasks/install_logging.yaml index 67904a9d3..3afd8680f 100644 --- a/roles/openshift_logging/tasks/install_logging.yaml +++ b/roles/openshift_logging/tasks/install_logging.yaml @@ -87,14 +87,14 @@ openshift_logging_elasticsearch_storage_type: "{{ elasticsearch_storage_type }}" openshift_logging_elasticsearch_pvc_pv_selector: "{{ openshift_logging_es_pv_selector }}" - openshift_logging_elasticsearch_pvc_storage_class_name: "{{ openshift_logging_es_pvc_storage_class_name }}" + openshift_logging_elasticsearch_pvc_storage_class_name: "{{ openshift_logging_es_pvc_storage_class_name | default() }}" openshift_logging_elasticsearch_nodeselector: "{{ openshift_logging_es_nodeselector if outer_item.0.nodeSelector | default(None) is none else outer_item.0.nodeSelector }}" openshift_logging_elasticsearch_storage_group: "{{ [openshift_logging_es_storage_group] if outer_item.0.storageGroups | default([]) | length == 0 else outer_item.0.storageGroups }}" _es_containers: "{{ outer_item.0.containers}}" _es_configmap: "{{ openshift_logging_facts | walk('elasticsearch#configmaps#logging-elasticsearch#elasticsearch.yml', '{}', delimiter='#') | from_yaml }}" with_together: - - "{{ openshift_logging_facts.elasticsearch.deploymentconfigs.values() }}" + - "{{ openshift_logging_facts.elasticsearch.deploymentconfigs.values() | list }}" - "{{ openshift_logging_facts.elasticsearch.pvcs }}" - "{{ es_indices }}" loop_control: @@ -114,7 +114,7 @@ openshift_logging_elasticsearch_storage_type: "{{ elasticsearch_storage_type }}" openshift_logging_elasticsearch_pvc_pv_selector: "{{ openshift_logging_es_pv_selector }}" - openshift_logging_elasticsearch_pvc_storage_class_name: "{{ openshift_logging_es_pvc_storage_class_name }}" + openshift_logging_elasticsearch_pvc_storage_class_name: "{{ openshift_logging_es_pvc_storage_class_name | default() }}" with_sequence: count={{ openshift_logging_es_cluster_size | int - openshift_logging_facts.elasticsearch.deploymentconfigs.keys() | count }} loop_control: @@ -151,7 +151,7 @@ openshift_logging_elasticsearch_pvc_size: "{{ openshift_logging_es_ops_pvc_size }}" openshift_logging_elasticsearch_pvc_dynamic: "{{ openshift_logging_es_ops_pvc_dynamic }}" openshift_logging_elasticsearch_pvc_pv_selector: "{{ openshift_logging_es_ops_pv_selector }}" - openshift_logging_elasticsearch_pvc_storage_class_name: "{{ openshift_logging_es_ops_pvc_storage_class_name }}" + openshift_logging_elasticsearch_pvc_storage_class_name: "{{ openshift_logging_es_ops_pvc_storage_class_name | default() }}" openshift_logging_elasticsearch_memory_limit: "{{ openshift_logging_es_ops_memory_limit }}" openshift_logging_elasticsearch_cpu_limit: "{{ openshift_logging_es_ops_cpu_limit }}" openshift_logging_elasticsearch_cpu_request: "{{ openshift_logging_es_ops_cpu_request }}" @@ -169,7 +169,7 @@ _es_configmap: "{{ openshift_logging_facts | walk('elasticsearch_ops#configmaps#logging-elasticsearch-ops#elasticsearch.yml', '{}', delimiter='#') | from_yaml }}" with_together: - - "{{ openshift_logging_facts.elasticsearch_ops.deploymentconfigs.values() }}" + - "{{ openshift_logging_facts.elasticsearch_ops.deploymentconfigs.values() | list }}" - "{{ openshift_logging_facts.elasticsearch_ops.pvcs }}" - "{{ es_ops_indices }}" loop_control: @@ -193,7 +193,7 @@ openshift_logging_elasticsearch_pvc_size: "{{ openshift_logging_es_ops_pvc_size }}" openshift_logging_elasticsearch_pvc_dynamic: "{{ openshift_logging_es_ops_pvc_dynamic }}" openshift_logging_elasticsearch_pvc_pv_selector: "{{ openshift_logging_es_ops_pv_selector }}" - openshift_logging_elasticsearch_pvc_storage_class_name: "{{ openshift_logging_es_ops_pvc_storage_class_name }}" + openshift_logging_elasticsearch_pvc_storage_class_name: "{{ openshift_logging_es_ops_pvc_storage_class_name | default() }}" openshift_logging_elasticsearch_memory_limit: "{{ openshift_logging_es_ops_memory_limit }}" openshift_logging_elasticsearch_cpu_limit: "{{ openshift_logging_es_ops_cpu_limit }}" openshift_logging_elasticsearch_cpu_request: "{{ openshift_logging_es_ops_cpu_request }}" @@ -321,9 +321,9 @@ - name: Add Kibana route information to web console asset config include_role: name: openshift_web_console - tasks_from: update_asset_config.yml + tasks_from: update_console_config.yml vars: - asset_config_edits: - - key: loggingPublicURL + console_config_edits: + - key: clusterInfo#loggingPublicURL value: "https://{{ openshift_logging_kibana_hostname }}" when: openshift_web_console_install | default(true) | bool diff --git a/roles/openshift_logging/tasks/procure_server_certs.yaml b/roles/openshift_logging/tasks/procure_server_certs.yaml index bc817075d..d28d1d160 100644 --- a/roles/openshift_logging/tasks/procure_server_certs.yaml +++ b/roles/openshift_logging/tasks/procure_server_certs.yaml @@ -30,7 +30,7 @@ {{ openshift_client_binary }} adm --config={{ mktemp.stdout }}/admin.kubeconfig ca create-server-cert --key={{generated_certs_dir}}/{{cert_info.procure_component}}.key --cert={{generated_certs_dir}}/{{cert_info.procure_component}}.crt --hostnames={{cert_info.hostnames|quote}} --signer-cert={{generated_certs_dir}}/ca.crt --signer-key={{generated_certs_dir}}/ca.key - --signer-serial={{generated_certs_dir}}/ca.serial.txt + --signer-serial={{generated_certs_dir}}/ca.serial.txt --overwrite=false check_mode: no when: - cert_info.hostnames is defined diff --git a/roles/openshift_logging_curator/vars/main.yml b/roles/openshift_logging_curator/vars/main.yml index 5bee58725..df5299a83 100644 --- a/roles/openshift_logging_curator/vars/main.yml +++ b/roles/openshift_logging_curator/vars/main.yml @@ -1,3 +1,3 @@ --- -__latest_curator_version: "3_8" -__allowed_curator_versions: ["3_5", "3_6", "3_7", "3_8"] +__latest_curator_version: "3_9" +__allowed_curator_versions: ["3_5", "3_6", "3_7", "3_8", "3_9"] diff --git a/roles/openshift_logging_elasticsearch/tasks/get_es_version.yml b/roles/openshift_logging_elasticsearch/tasks/get_es_version.yml index 9182bddb2..16de6f252 100644 --- a/roles/openshift_logging_elasticsearch/tasks/get_es_version.yml +++ b/roles/openshift_logging_elasticsearch/tasks/get_es_version.yml @@ -1,6 +1,6 @@ --- - command: > - oc get pod -l component=es,provider=openshift -n {{ openshift_logging_elasticsearch_namespace }} -o jsonpath={.items[*].metadata.name} + oc get pod -l component=es,provider=openshift -n {{ openshift_logging_elasticsearch_namespace }} -o jsonpath={.items[?(@.status.phase==\"Running\")].metadata.name} register: _cluster_pods - name: "Getting ES version for logging-es cluster" @@ -10,7 +10,7 @@ when: _cluster_pods.stdout_lines | count > 0 - command: > - oc get pod -l component=es-ops,provider=openshift -n {{ openshift_logging_elasticsearch_namespace }} -o jsonpath={.items[*].metadata.name} + oc get pod -l component=es-ops,provider=openshift -n {{ openshift_logging_elasticsearch_namespace }} -o jsonpath={.items[?(@.status.phase==\"Running\")].metadata.name} register: _ops_cluster_pods - name: "Getting ES version for logging-es-ops cluster" diff --git a/roles/openshift_logging_elasticsearch/tasks/restart_cluster.yml b/roles/openshift_logging_elasticsearch/tasks/restart_cluster.yml index d55beec86..6bce13d1d 100644 --- a/roles/openshift_logging_elasticsearch/tasks/restart_cluster.yml +++ b/roles/openshift_logging_elasticsearch/tasks/restart_cluster.yml @@ -19,7 +19,7 @@ ## get all pods for the cluster - command: > - oc get pod -l component={{ _cluster_component }},provider=openshift -n {{ openshift_logging_elasticsearch_namespace }} -o jsonpath={.items[*].metadata.name} + oc get pod -l component={{ _cluster_component }},provider=openshift -n {{ openshift_logging_elasticsearch_namespace }} -o jsonpath={.items[?(@.status.phase==\"Running\")].metadata.name} register: _cluster_pods - name: "Disable shard balancing for logging-{{ _cluster_component }} cluster" @@ -64,7 +64,7 @@ ## we may need a new first pod to run against -- fetch them all again - command: > - oc get pod -l component={{ _cluster_component }},provider=openshift -n {{ openshift_logging_elasticsearch_namespace }} -o jsonpath={.items[*].metadata.name} + oc get pod -l component={{ _cluster_component }},provider=openshift -n {{ openshift_logging_elasticsearch_namespace }} -o jsonpath={.items[?(@.status.phase==\"Running\")].metadata.name} register: _cluster_pods - name: "Enable shard balancing for logging-{{ _cluster_component }} cluster" diff --git a/roles/openshift_logging_elasticsearch/vars/main.yml b/roles/openshift_logging_elasticsearch/vars/main.yml index ef259cd3a..122231031 100644 --- a/roles/openshift_logging_elasticsearch/vars/main.yml +++ b/roles/openshift_logging_elasticsearch/vars/main.yml @@ -1,6 +1,6 @@ --- -__latest_es_version: "3_8" -__allowed_es_versions: ["3_5", "3_6", "3_7", "3_8"] +__latest_es_version: "3_9" +__allowed_es_versions: ["3_5", "3_6", "3_7", "3_8", "3_9"] __allowed_es_types: ["data-master", "data-client", "master", "client"] __es_log_appenders: ['file', 'console'] __kibana_index_modes: ["unique", "shared_ops"] diff --git a/roles/openshift_logging_fluentd/defaults/main.yml b/roles/openshift_logging_fluentd/defaults/main.yml index 9b58e4456..87b4204b5 100644 --- a/roles/openshift_logging_fluentd/defaults/main.yml +++ b/roles/openshift_logging_fluentd/defaults/main.yml @@ -5,6 +5,7 @@ openshift_logging_fluentd_master_url: "https://kubernetes.default.svc.{{ openshi openshift_logging_fluentd_namespace: logging ### Common settings +# map_from_pairs is a custom filter plugin in role lib_utils openshift_logging_fluentd_nodeselector: "{{ openshift_hosted_logging_fluentd_nodeselector_label | default('logging-infra-fluentd=true') | map_from_pairs }}" openshift_logging_fluentd_cpu_limit: null openshift_logging_fluentd_cpu_request: 100m diff --git a/roles/openshift_logging_fluentd/tasks/main.yaml b/roles/openshift_logging_fluentd/tasks/main.yaml index 529859983..79ebbca08 100644 --- a/roles/openshift_logging_fluentd/tasks/main.yaml +++ b/roles/openshift_logging_fluentd/tasks/main.yaml @@ -172,8 +172,8 @@ app_port: "{{ openshift_logging_fluentd_app_port }}" ops_host: "{{ openshift_logging_fluentd_ops_host }}" ops_port: "{{ openshift_logging_fluentd_ops_port }}" - fluentd_nodeselector_key: "{{ openshift_logging_fluentd_nodeselector.keys()[0] }}" - fluentd_nodeselector_value: "{{ openshift_logging_fluentd_nodeselector.values()[0] }}" + fluentd_nodeselector_key: "{{ openshift_logging_fluentd_nodeselector.keys() | first }}" + fluentd_nodeselector_value: "{{ openshift_logging_fluentd_nodeselector.values() | first }}" fluentd_cpu_limit: "{{ openshift_logging_fluentd_cpu_limit }}" fluentd_cpu_request: "{{ openshift_logging_fluentd_cpu_request | min_cpu(openshift_logging_fluentd_cpu_limit | default(none)) }}" fluentd_memory_limit: "{{ openshift_logging_fluentd_memory_limit }}" diff --git a/roles/openshift_logging_fluentd/vars/main.yml b/roles/openshift_logging_fluentd/vars/main.yml index 762e3d4d0..b60da814f 100644 --- a/roles/openshift_logging_fluentd/vars/main.yml +++ b/roles/openshift_logging_fluentd/vars/main.yml @@ -1,5 +1,5 @@ --- -__latest_fluentd_version: "3_8" -__allowed_fluentd_versions: ["3_5", "3_6", "3_7", "3_8"] +__latest_fluentd_version: "3_9" +__allowed_fluentd_versions: ["3_5", "3_6", "3_7", "3_8", "3_9"] __allowed_fluentd_types: ["hosted", "secure-aggregator", "secure-host"] __allowed_mux_client_modes: ["minimal", "maximal"] diff --git a/roles/openshift_logging_kibana/vars/main.yml b/roles/openshift_logging_kibana/vars/main.yml index a2c54d8e4..fed926a3b 100644 --- a/roles/openshift_logging_kibana/vars/main.yml +++ b/roles/openshift_logging_kibana/vars/main.yml @@ -1,3 +1,3 @@ --- -__latest_kibana_version: "3_8" -__allowed_kibana_versions: ["3_5", "3_6", "3_7", "3_8"] +__latest_kibana_version: "3_9" +__allowed_kibana_versions: ["3_5", "3_6", "3_7", "3_8", "3_9"] diff --git a/roles/openshift_logging_mux/defaults/main.yml b/roles/openshift_logging_mux/defaults/main.yml index db6f23126..e87c8d33e 100644 --- a/roles/openshift_logging_mux/defaults/main.yml +++ b/roles/openshift_logging_mux/defaults/main.yml @@ -6,6 +6,7 @@ openshift_logging_mux_master_public_url: "{{ openshift_hosted_logging_master_pub openshift_logging_mux_namespace: logging ### Common settings +# map_from_pairs is a custom filter plugin in role lib_utils openshift_logging_mux_nodeselector: "{{ openshift_hosted_logging_mux_nodeselector_label | default('') | map_from_pairs }}" openshift_logging_mux_cpu_limit: null openshift_logging_mux_cpu_request: 100m @@ -30,6 +31,7 @@ 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 }}" openshift_logging_mux_port: 24284 +openshift_logging_mux_external_address: "{{ ansible_default_ipv4.address }}" # 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"] diff --git a/roles/openshift_logging_mux/tasks/main.yaml b/roles/openshift_logging_mux/tasks/main.yaml index 34bdb891c..7eba3cda4 100644 --- a/roles/openshift_logging_mux/tasks/main.yaml +++ b/roles/openshift_logging_mux/tasks/main.yaml @@ -148,7 +148,7 @@ port: "{{ openshift_logging_mux_port }}" targetPort: "mux-forward" external_ips: - - "{{ ansible_eth0.ipv4.address }}" + - "{{ openshift_logging_mux_external_address }}" when: openshift_logging_mux_allow_external | bool - name: Set logging-mux service for internal communication diff --git a/roles/openshift_logging_mux/vars/main.yml b/roles/openshift_logging_mux/vars/main.yml index 1da053b4a..e87205bad 100644 --- a/roles/openshift_logging_mux/vars/main.yml +++ b/roles/openshift_logging_mux/vars/main.yml @@ -1,3 +1,3 @@ --- -__latest_mux_version: "3_8" -__allowed_mux_versions: ["3_5", "3_6", "3_7", "3_8"] +__latest_mux_version: "3_9" +__allowed_mux_versions: ["3_5", "3_6", "3_7", "3_8", "3_9"] diff --git a/roles/openshift_master/tasks/main.yml b/roles/openshift_master/tasks/main.yml index eea1401b8..b12a6b346 100644 --- a/roles/openshift_master/tasks/main.yml +++ b/roles/openshift_master/tasks/main.yml @@ -181,6 +181,7 @@ - restart master api - set_fact: + # translate_idps is a custom filter in role lib_utils translated_identity_providers: "{{ openshift.master.identity_providers | translate_idps('v1') }}" # TODO: add the validate parameter when there is a validation command to run diff --git a/roles/openshift_master/tasks/upgrade/rpm_upgrade.yml b/roles/openshift_master/tasks/upgrade/rpm_upgrade.yml index f72710832..4564f33dd 100644 --- a/roles/openshift_master/tasks/upgrade/rpm_upgrade.yml +++ b/roles/openshift_master/tasks/upgrade/rpm_upgrade.yml @@ -8,8 +8,25 @@ # TODO: If the sdn package isn't already installed this will install it, we # should fix that -- name: Upgrade master packages - package: name={{ master_pkgs | join(',') }} state=present +- name: Upgrade master packages - yum + command: + yum install -y {{ master_pkgs | join(' ') }} \ + {{ ' --exclude *' ~ openshift_service_type ~ '*3.9*' if openshift_release | version_compare('3.9','<') else '' }} + vars: + master_pkgs: + - "{{ openshift_service_type }}{{ openshift_pkg_version | default('') }}" + - "{{ openshift_service_type }}-master{{ openshift_pkg_version | default('') }}" + - "{{ openshift_service_type }}-node{{ openshift_pkg_version | default('') }}" + - "{{ openshift_service_type }}-sdn-ovs{{ openshift_pkg_version | default('') }}" + - "{{ openshift_service_type }}-clients{{ openshift_pkg_version | default('') }}" + register: result + until: result is succeeded + when: ansible_pkg_mgr == 'yum' + +- name: Upgrade master packages - dnf + dnf: + name: "{{ master_pkgs | join(',') }}" + state: present vars: master_pkgs: - "{{ openshift_service_type }}{{ openshift_pkg_version }}" @@ -17,6 +34,6 @@ - "{{ openshift_service_type }}-node{{ openshift_pkg_version }}" - "{{ openshift_service_type }}-sdn-ovs{{ openshift_pkg_version }}" - "{{ openshift_service_type }}-clients{{ openshift_pkg_version }}" - - "tuned-profiles-{{ openshift_service_type }}-node{{ openshift_pkg_version }}" register: result until: result is succeeded + when: ansible_pkg_mgr == 'dnf' diff --git a/roles/openshift_master/tasks/upgrade/upgrade_scheduler.yml b/roles/openshift_master/tasks/upgrade/upgrade_scheduler.yml index 8558bf3e9..995a5ab70 100644 --- a/roles/openshift_master/tasks/upgrade/upgrade_scheduler.yml +++ b/roles/openshift_master/tasks/upgrade/upgrade_scheduler.yml @@ -1,6 +1,8 @@ --- # Upgrade predicates - vars: + # openshift_master_facts_default_predicates is a custom lookup plugin in + # role lib_utils prev_predicates: "{{ lookup('openshift_master_facts_default_predicates', short_version=openshift_upgrade_min, deployment_type=openshift_deployment_type) }}" prev_predicates_no_region: "{{ lookup('openshift_master_facts_default_predicates', short_version=openshift_upgrade_min, deployment_type=openshift_deployment_type, regions_enabled=False) }}" default_predicates_no_region: "{{ lookup('openshift_master_facts_default_predicates', regions_enabled=False) }}" diff --git a/roles/openshift_master_certificates/tasks/main.yml b/roles/openshift_master_certificates/tasks/main.yml index 649a4bc5d..ce27e238f 100644 --- a/roles/openshift_master_certificates/tasks/main.yml +++ b/roles/openshift_master_certificates/tasks/main.yml @@ -101,6 +101,7 @@ state: hard force: true with_items: + # certificates_to_synchronize is a custom filter in lib_utils - "{{ hostvars[inventory_hostname] | certificates_to_synchronize }}" when: master_certs_missing | bool and inventory_hostname != openshift_ca_host delegate_to: "{{ openshift_ca_host }}" diff --git a/roles/openshift_master_facts/tasks/main.yml b/roles/openshift_master_facts/tasks/main.yml index 85d0ac25c..f450c916a 100644 --- a/roles/openshift_master_facts/tasks/main.yml +++ b/roles/openshift_master_facts/tasks/main.yml @@ -57,6 +57,7 @@ access_token_max_seconds: "{{ openshift_master_access_token_max_seconds | default(None) }}" auth_token_max_seconds: "{{ openshift_master_auth_token_max_seconds | default(None) }}" identity_providers: "{{ openshift_master_identity_providers | default(None) }}" + # oo_htpasswd_users_from_file is a custom filter in role lib_utils htpasswd_users: "{{ openshift_master_htpasswd_users | default(lookup('file', openshift_master_htpasswd_file) | oo_htpasswd_users_from_file if openshift_master_htpasswd_file is defined else None) }}" manage_htpasswd: "{{ openshift_master_manage_htpasswd | default(true) }}" ldap_ca: "{{ openshift_master_ldap_ca | default(lookup('file', openshift_master_ldap_ca_file) if openshift_master_ldap_ca_file is defined else None) }}" @@ -90,6 +91,8 @@ - name: Set Default scheduler predicates and priorities set_fact: + # openshift_master_facts_default_predicates is a custom lookup plugin in + # role lib_utils openshift_master_scheduler_default_predicates: "{{ lookup('openshift_master_facts_default_predicates') }}" openshift_master_scheduler_default_priorities: "{{ lookup('openshift_master_facts_default_priorities') }}" diff --git a/roles/openshift_metrics/tasks/install_metrics.yaml b/roles/openshift_metrics/tasks/install_metrics.yaml index 0866fe0d2..0dd5d1621 100644 --- a/roles/openshift_metrics/tasks/install_metrics.yaml +++ b/roles/openshift_metrics/tasks/install_metrics.yaml @@ -74,10 +74,10 @@ - name: Add metrics route information to web console asset config include_role: name: openshift_web_console - tasks_from: update_asset_config.yml + tasks_from: update_console_config.yml vars: - asset_config_edits: - - key: metricsPublicURL + console_config_edits: + - key: clusterInfo#metricsPublicURL value: "https://{{ openshift_metrics_hawkular_hostname}}/hawkular/metrics" when: openshift_web_console_install | default(true) | bool diff --git a/roles/openshift_metrics/tasks/oc_apply.yaml b/roles/openshift_metrics/tasks/oc_apply.yaml index 8ccfb7192..057963c1a 100644 --- a/roles/openshift_metrics/tasks/oc_apply.yaml +++ b/roles/openshift_metrics/tasks/oc_apply.yaml @@ -16,7 +16,9 @@ apply -f {{ file_name }} -n {{namespace}} register: generation_apply - failed_when: "'error' in generation_apply.stderr" + failed_when: + - "'error' in generation_apply.stderr" + - "generation_apply.rc != 0" changed_when: no - name: Determine change status of {{file_content.kind}} {{file_content.metadata.name}} @@ -28,5 +30,7 @@ register: version_changed vars: init_version: "{{ (generation_init is defined) | ternary(generation_init.stdout, '0') }}" - failed_when: "'error' in version_changed.stderr" + failed_when: + - "'error' in version_changed.stderr" + - "version_changed.rc != 0" changed_when: version_changed.stdout | int > init_version | int diff --git a/roles/openshift_metrics/tasks/uninstall_metrics.yaml b/roles/openshift_metrics/tasks/uninstall_metrics.yaml index 610c7b4e5..1664e9975 100644 --- a/roles/openshift_metrics/tasks/uninstall_metrics.yaml +++ b/roles/openshift_metrics/tasks/uninstall_metrics.yaml @@ -19,13 +19,13 @@ clusterrolebinding/hawkular-metrics changed_when: delete_metrics.stdout != 'No resources found' -# Update asset config in openshift-web-console namespace -- name: Remove metrics route information from web console asset config +# Update the web config in openshift-web-console namespace +- name: Remove metrics route information from the web console config include_role: name: openshift_web_console - tasks_from: update_asset_config.yml + tasks_from: update_console_config.yml vars: - asset_config_edits: - - key: metricsPublicURL + console_config_edits: + - key: clusterInfo#metricsPublicURL value: "" when: openshift_web_console_install | default(true) | bool diff --git a/roles/openshift_named_certificates/filter_plugins/openshift_named_certificates.py b/roles/openshift_named_certificates/filter_plugins/openshift_named_certificates.py deleted file mode 100644 index 6ed6d404c..000000000 --- a/roles/openshift_named_certificates/filter_plugins/openshift_named_certificates.py +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -''' -Custom filters for use with openshift named certificates -''' - - -class FilterModule(object): - ''' Custom ansible filters for use with openshift named certificates''' - - @staticmethod - def oo_named_certificates_list(named_certificates): - ''' Returns named certificates list with correct fields for the master - config file.''' - return [{'certFile': named_certificate['certfile'], - 'keyFile': named_certificate['keyfile'], - 'names': named_certificate['names']} for named_certificate in named_certificates] - - def filters(self): - ''' returns a mapping of filters to methods ''' - return {"oo_named_certificates_list": self.oo_named_certificates_list} diff --git a/roles/openshift_node/defaults/main.yml b/roles/openshift_node/defaults/main.yml index c1fab4382..5864d3c03 100644 --- a/roles/openshift_node/defaults/main.yml +++ b/roles/openshift_node/defaults/main.yml @@ -48,6 +48,12 @@ openshift_node_kubelet_args_dict: cloud-config: - "{{ openshift_config_base ~ '/cloudprovider/gce.conf' }}" node-labels: "{{ l_node_kubelet_node_labels }}" + azure: + cloud-provider: + - azure + cloud-config: + - "{{ openshift_config_base ~ '/cloudprovider/azure.conf' }}" + node-labels: "{{ l_node_kubelet_node_labels }}" undefined: node-labels: "{{ l_node_kubelet_node_labels }}" @@ -71,6 +77,18 @@ r_openshift_node_use_firewalld: "{{ os_firewall_use_firewalld | default(False) } l_is_node_system_container: "{{ (openshift_use_node_system_container | default(openshift_use_system_containers | default(false)) | bool) }}" +openshift_node_syscon_auth_mounts_l: +- type: bind + source: "{{ oreg_auth_credentials_path }}" + destination: "/root/.docker" + options: + - ro + +# If we need to add new mounts in the future, or the user wants to mount data. +# This should be in the same format as auth_mounts_l above. +openshift_node_syscon_add_mounts_l: [] + + openshift_deployment_type: "{{ openshift_deployment_type | default('origin') }}" openshift_node_image_dict: diff --git a/roles/openshift_node/tasks/install.yml b/roles/openshift_node/tasks/install.yml index 55738d759..a4a9c1237 100644 --- a/roles/openshift_node/tasks/install.yml +++ b/roles/openshift_node/tasks/install.yml @@ -1,28 +1,18 @@ --- -- when: not openshift_is_containerized | bool - block: - - name: Install Node package - package: - name: "{{ openshift_service_type }}-node{{ (openshift_pkg_version | default('')) | lib_utils_oo_image_tag_to_rpm_version(include_dash=True) }}" - state: present - register: result - until: result is succeeded - - - name: Install sdn-ovs package - package: - name: "{{ openshift_service_type }}-sdn-ovs{{ (openshift_pkg_version | default('')) | lib_utils_oo_image_tag_to_rpm_version(include_dash=True) }}" - state: present - when: - - openshift_node_use_openshift_sdn | bool - register: result - until: result is succeeded - - - name: Install conntrack-tools package - package: - name: "conntrack-tools" - state: present - register: result - until: result is succeeded +- name: Install Node package, sdn-ovs, conntrack packages + package: + name: "{{ item.name }}" + state: present + register: result + until: result is succeeded + with_items: + - name: "{{ openshift_service_type }}-node{{ (openshift_pkg_version | default('')) | lib_utils_oo_image_tag_to_rpm_version(include_dash=True) }}" + - name: "{{ openshift_service_type }}-sdn-ovs{{ (openshift_pkg_version | default('')) | lib_utils_oo_image_tag_to_rpm_version(include_dash=True) }}" + install: "{{ openshift_node_use_openshift_sdn | bool }}" + - name: "conntrack-tools" + when: + - not openshift_is_containerized | bool + - item['install'] | default(True) | bool - when: - openshift_is_containerized | bool diff --git a/roles/openshift_node/tasks/node_system_container.yml b/roles/openshift_node/tasks/node_system_container.yml index 06b879050..008f209d7 100644 --- a/roles/openshift_node/tasks/node_system_container.yml +++ b/roles/openshift_node/tasks/node_system_container.yml @@ -14,4 +14,23 @@ - "DNS_DOMAIN={{ openshift.common.dns_domain }}" - "DOCKER_SERVICE={{ openshift_docker_service_name }}.service" - "MASTER_SERVICE={{ openshift_service_type }}.service" + - 'ADDTL_MOUNTS={{ l_node_syscon_add_mounts2 }}' state: latest + vars: + # We need to evaluate some variables here to ensure + # l_bind_docker_reg_auth is evaluated after registry_auth.yml has been + # processed. + + # Determine if we want to include auth credentials mount. + l_node_syscon_auth_mounts_l: "{{ l_bind_docker_reg_auth | ternary(openshift_node_syscon_auth_mounts_l,[]) }}" + + # Join any user-provided mounts and auth_mounts into a combined list. + l_node_syscon_add_mounts_l: "{{ openshift_node_syscon_add_mounts_l | union(l_node_syscon_auth_mounts_l) }}" + + # We must prepend a ',' here to ensure the value is inserted properly into an + # existing json list in the container's config.json + # lib_utils_oo_l_of_d_to_csv is a custom filter plugin in roles/lib_utils/oo_filters.py + l_node_syscon_add_mounts: ",{{ l_node_syscon_add_mounts_l | lib_utils_oo_l_of_d_to_csv }}" + # if we have just a ',' then both mount lists were empty, we don't want to add + # anything to config.json + l_node_syscon_add_mounts2: "{{ (l_node_syscon_add_mounts != ',') | bool | ternary(l_node_syscon_add_mounts,'') }}" diff --git a/roles/openshift_node/tasks/upgrade/config_changes.yml b/roles/openshift_node/tasks/upgrade/config_changes.yml index 721656117..dd9183382 100644 --- a/roles/openshift_node/tasks/upgrade/config_changes.yml +++ b/roles/openshift_node/tasks/upgrade/config_changes.yml @@ -21,6 +21,12 @@ path: "/var/lib/dockershim/sandbox/" state: absent +# https://bugzilla.redhat.com/show_bug.cgi?id=1518912 +- name: Clean up IPAM data + file: + path: "/var/lib/cni/networks/openshift-sdn/" + state: absent + # Disable Swap Block (pre) - block: - name: Remove swap entries from /etc/fstab diff --git a/roles/openshift_node/tasks/upgrade/rpm_upgrade.yml b/roles/openshift_node/tasks/upgrade/rpm_upgrade.yml index 91a358095..d4b47bb9e 100644 --- a/roles/openshift_node/tasks/upgrade/rpm_upgrade.yml +++ b/roles/openshift_node/tasks/upgrade/rpm_upgrade.yml @@ -12,7 +12,7 @@ until: result is succeeded vars: openshift_node_upgrade_rpm_list: - - "{{ openshift_service_type }}-node{{ openshift_pkg_version }}" + - "{{ openshift_service_type }}-node{{ openshift_pkg_version | default('') }}" - "PyYAML" - "dnsmasq" diff --git a/roles/openshift_node/tasks/upgrade/rpm_upgrade_install.yml b/roles/openshift_node/tasks/upgrade/rpm_upgrade_install.yml index c9094e05a..ef5d8d662 100644 --- a/roles/openshift_node/tasks/upgrade/rpm_upgrade_install.yml +++ b/roles/openshift_node/tasks/upgrade/rpm_upgrade_install.yml @@ -14,6 +14,6 @@ until: result is succeeded vars: openshift_node_upgrade_rpm_list: - - "{{ openshift_service_type }}-node{{ openshift_pkg_version }}" + - "{{ openshift_service_type }}-node{{ openshift_pkg_version | default('') }}" - "PyYAML" - "openvswitch" diff --git a/roles/openshift_openstack/templates/heat_stack.yaml.j2 b/roles/openshift_openstack/templates/heat_stack.yaml.j2 index 1be5d3a62..8e7c6288a 100644 --- a/roles/openshift_openstack/templates/heat_stack.yaml.j2 +++ b/roles/openshift_openstack/templates/heat_stack.yaml.j2 @@ -523,7 +523,7 @@ resources: floating_network: if: - no_floating - - null + - '' - {{ openshift_openstack_external_network_name }} {% if openshift_openstack_provider_network_name %} attach_float_net: false @@ -589,8 +589,13 @@ resources: secgrp: - { get_resource: lb-secgrp } - { get_resource: common-secgrp } -{% if not openshift_openstack_provider_network_name %} - floating_network: {{ openshift_openstack_external_network_name }} + floating_network: + if: + - no_floating + - '' + - {{ openshift_openstack_external_network_name }} +{% if openshift_openstack_provider_network_name %} + attach_float_net: false {% endif %} volume_size: {{ openshift_openstack_lb_volume_size }} {% if not openshift_openstack_provider_network_name %} @@ -655,7 +660,7 @@ resources: floating_network: if: - no_floating - - null + - '' - {{ openshift_openstack_external_network_name }} {% if openshift_openstack_provider_network_name %} attach_float_net: false @@ -725,7 +730,7 @@ resources: floating_network: if: - no_floating - - null + - '' - {{ openshift_openstack_external_network_name }} {% if openshift_openstack_provider_network_name %} attach_float_net: false @@ -792,8 +797,13 @@ resources: {% endif %} - { get_resource: infra-secgrp } - { get_resource: common-secgrp } -{% if not openshift_openstack_provider_network_name %} - floating_network: {{ openshift_openstack_external_network_name }} + floating_network: + if: + - no_floating + - '' + - {{ openshift_openstack_external_network_name }} +{% if openshift_openstack_provider_network_name %} + attach_float_net: false {% endif %} volume_size: {{ openshift_openstack_infra_volume_size }} {% if openshift_openstack_infra_server_group_policies|length > 0 %} diff --git a/roles/openshift_openstack/templates/heat_stack_server.yaml.j2 b/roles/openshift_openstack/templates/heat_stack_server.yaml.j2 index a829da34f..29b09f3c9 100644 --- a/roles/openshift_openstack/templates/heat_stack_server.yaml.j2 +++ b/roles/openshift_openstack/templates/heat_stack_server.yaml.j2 @@ -102,13 +102,11 @@ parameters: label: Attach-float-net description: A switch for floating network port connection -{% if not openshift_openstack_provider_network_name %} floating_network: type: string default: '' label: Floating network description: Network to allocate floating IP from -{% endif %} availability_zone: type: string @@ -212,6 +210,9 @@ resources: host-type: { get_param: type } sub-host-type: { get_param: subtype } node_labels: { get_param: node_labels } +{% if openshift_openstack_dns_nameservers %} + openshift_hostname: { get_param: name } +{% endif %} scheduler_hints: { get_param: scheduler_hints } {% if use_trunk_ports|default(false)|bool %} diff --git a/roles/openshift_persistent_volumes/tasks/main.yml b/roles/openshift_persistent_volumes/tasks/main.yml index 0b4dd7d1f..b1d9c8cca 100644 --- a/roles/openshift_persistent_volumes/tasks/main.yml +++ b/roles/openshift_persistent_volumes/tasks/main.yml @@ -26,7 +26,8 @@ when: openshift_hosted_registry_storage_glusterfs_swap | default(False) - name: create standard pv and pvc lists - # generate_pv_pvcs_list is a custom action module defined in ../action_plugins + # generate_pv_pvcs_list is a custom action module defined in + # roles/lib_utils/action_plugins/generate_pv_pvcs_list.py generate_pv_pvcs_list: {} register: l_pv_pvcs_list diff --git a/roles/openshift_persistent_volumes/tasks/pv.yml b/roles/openshift_persistent_volumes/tasks/pv.yml index ef9ab7f5f..865269b7a 100644 --- a/roles/openshift_persistent_volumes/tasks/pv.yml +++ b/roles/openshift_persistent_volumes/tasks/pv.yml @@ -13,5 +13,5 @@ --config={{ mktemp.stdout }}/admin.kubeconfig register: pv_create_output when: persistent_volumes | length > 0 - failed_when: ('already exists' not in pv_create_output.stderr) and ('created' not in pv_create_output.stdout) + failed_when: "('already exists' not in pv_create_output.stderr) and ('created' not in pv_create_output.stdout) and pv_create_output.rc != 0" changed_when: ('created' in pv_create_output.stdout) diff --git a/roles/openshift_persistent_volumes/tasks/pvc.yml b/roles/openshift_persistent_volumes/tasks/pvc.yml index 2c5519192..6c12d128c 100644 --- a/roles/openshift_persistent_volumes/tasks/pvc.yml +++ b/roles/openshift_persistent_volumes/tasks/pvc.yml @@ -13,5 +13,5 @@ --config={{ mktemp.stdout }}/admin.kubeconfig register: pvc_create_output when: persistent_volume_claims | length > 0 - failed_when: ('already exists' not in pvc_create_output.stderr) and ('created' not in pvc_create_output.stdout) + failed_when: "('already exists' not in pvc_create_output.stderr) and ('created' not in pvc_create_output.stdout) and pvc_create_output.rc != 0" changed_when: ('created' in pvc_create_output.stdout) diff --git a/roles/openshift_provisioners/tasks/oc_apply.yaml b/roles/openshift_provisioners/tasks/oc_apply.yaml index a4ce53eae..239e1f1cc 100644 --- a/roles/openshift_provisioners/tasks/oc_apply.yaml +++ b/roles/openshift_provisioners/tasks/oc_apply.yaml @@ -15,7 +15,9 @@ apply -f {{ file_name }} -n {{ namespace }} register: generation_apply - failed_when: "'error' in generation_apply.stderr" + failed_when: + - "'error' in generation_apply.stderr" + - "generation_apply.rc != 0" changed_when: no - name: Determine change status of {{file_content.kind}} {{file_content.metadata.name}} @@ -36,7 +38,9 @@ delete -f {{ file_name }} -n {{ namespace }} register: generation_delete - failed_when: "'error' in generation_delete.stderr" + failed_when: + - "'error' in generation_delete.stderr" + - "generation_delete.rc != 0" changed_when: generation_delete.rc == 0 when: generation_apply.rc != 0 @@ -46,6 +50,8 @@ apply -f {{ file_name }} -n {{ namespace }} register: generation_apply - failed_when: "'error' in generation_apply.stderr" + failed_when: + - "'error' in generation_apply.stderr" + - "generation_apply.rc != 0" changed_when: generation_apply.rc == 0 when: generation_apply.rc != 0 diff --git a/roles/openshift_sanitize_inventory/filter_plugins/openshift_sanitize_inventory.py b/roles/openshift_sanitize_inventory/filter_plugins/openshift_sanitize_inventory.py index 72c47b8ee..14f1f72c2 100644 --- a/roles/openshift_sanitize_inventory/filter_plugins/openshift_sanitize_inventory.py +++ b/roles/openshift_sanitize_inventory/filter_plugins/openshift_sanitize_inventory.py @@ -6,15 +6,6 @@ import re -# This should be removed after map_from_pairs is no longer used in __deprecations_logging.yml -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 vars_with_pattern(source, pattern=""): ''' Returns a list of variables whose name matches the given pattern ''' if source == '': @@ -39,6 +30,5 @@ class FilterModule(object): def filters(self): ''' Returns the names of the filters provided by this class ''' return { - 'map_from_pairs': map_from_pairs, 'vars_with_pattern': vars_with_pattern } diff --git a/roles/openshift_service_catalog/defaults/main.yml b/roles/openshift_service_catalog/defaults/main.yml index 7c848cb12..15ca9838c 100644 --- a/roles/openshift_service_catalog/defaults/main.yml +++ b/roles/openshift_service_catalog/defaults/main.yml @@ -1,6 +1,7 @@ --- openshift_service_catalog_remove: false openshift_service_catalog_nodeselector: {"openshift-infra": "apiserver"} +openshift_service_catalog_async_bindings_enabled: false openshift_use_openshift_sdn: True # os_sdn_network_plugin_name: "{% if openshift_use_openshift_sdn %}redhat/openshift-ovs-subnet{% else %}{% endif %}" diff --git a/roles/openshift_service_catalog/tasks/generate_certs.yml b/roles/openshift_service_catalog/tasks/generate_certs.yml index e478023f8..72110b18c 100644 --- a/roles/openshift_service_catalog/tasks/generate_certs.yml +++ b/roles/openshift_service_catalog/tasks/generate_certs.yml @@ -59,11 +59,6 @@ src: "{{ generated_certs_dir }}/ca.crt" register: apiserver_ca -- shell: > - {{ openshift_client_binary }} --config=/etc/origin/master/admin.kubeconfig get apiservices.apiregistration.k8s.io/v1beta1.servicecatalog.k8s.io -n kube-service-catalog || echo "not found" - register: get_apiservices - changed_when: no - - name: Create api service oc_obj: state: present @@ -86,4 +81,3 @@ caBundle: "{{ apiserver_ca.content }}" groupPriorityMinimum: 20 versionPriority: 10 - when: "'not found' in get_apiservices.stdout" diff --git a/roles/openshift_service_catalog/tasks/install.yml b/roles/openshift_service_catalog/tasks/install.yml index cfecaa12c..9b38a85c4 100644 --- a/roles/openshift_service_catalog/tasks/install.yml +++ b/roles/openshift_service_catalog/tasks/install.yml @@ -179,6 +179,8 @@ etcd_servers: "{{ openshift.master.etcd_urls | join(',') }}" etcd_cafile: "{{ '/etc/origin/master/master.etcd-ca.crt' if etcd_ca_crt.stat.exists else '/etc/origin/master/ca-bundle.crt' }}" node_selector: "{{ openshift_service_catalog_nodeselector | default ({'openshift-infra': 'apiserver'}) }}" + # apiserver_ca is defined in generate_certs.yml + ca_hash: "{{ apiserver_ca.content|hash('sha1') }}" - name: Set Service Catalog API Server daemonset oc_obj: diff --git a/roles/openshift_service_catalog/templates/api_server.j2 b/roles/openshift_service_catalog/templates/api_server.j2 index 4f51b8c3c..e345df32c 100644 --- a/roles/openshift_service_catalog/templates/api_server.j2 +++ b/roles/openshift_service_catalog/templates/api_server.j2 @@ -14,6 +14,8 @@ spec: type: RollingUpdate template: metadata: + annotations: + ca_hash: {{ ca_hash }} labels: app: apiserver spec: diff --git a/roles/openshift_service_catalog/templates/controller_manager.j2 b/roles/openshift_service_catalog/templates/controller_manager.j2 index 137222f04..c61e05f73 100644 --- a/roles/openshift_service_catalog/templates/controller_manager.j2 +++ b/roles/openshift_service_catalog/templates/controller_manager.j2 @@ -8,7 +8,7 @@ spec: selector: matchLabels: app: controller-manager - strategy: + updateStrategy: rollingUpdate: maxUnavailable: 1 type: RollingUpdate @@ -38,6 +38,10 @@ spec: - "5m" - --feature-gates - OriginatingIdentity=true +{% if openshift_service_catalog_async_bindings_enabled | bool %} + - --feature-gates + - AsyncBindingOperations=true +{% endif %} image: {{ openshift_service_catalog_image_prefix }}service-catalog:{{ openshift_service_catalog_image_version }} command: ["/usr/bin/service-catalog"] imagePullPolicy: Always diff --git a/roles/openshift_storage_glusterfs/files/v3.9/deploy-heketi-template.yml b/roles/openshift_storage_glusterfs/files/v3.9/deploy-heketi-template.yml new file mode 100644 index 000000000..34af652c2 --- /dev/null +++ b/roles/openshift_storage_glusterfs/files/v3.9/deploy-heketi-template.yml @@ -0,0 +1,133 @@ +--- +kind: Template +apiVersion: v1 +metadata: + name: deploy-heketi + labels: + glusterfs: heketi-template + deploy-heketi: support + annotations: + description: Bootstrap Heketi installation + tags: glusterfs,heketi,installation +objects: +- kind: Service + apiVersion: v1 + metadata: + name: deploy-heketi-${CLUSTER_NAME} + labels: + glusterfs: deploy-heketi-${CLUSTER_NAME}-service + deploy-heketi: support + annotations: + description: Exposes Heketi service + spec: + ports: + - name: deploy-heketi-${CLUSTER_NAME} + port: 8080 + targetPort: 8080 + selector: + glusterfs: deploy-heketi-${CLUSTER_NAME}-pod +- kind: Route + apiVersion: v1 + metadata: + name: ${HEKETI_ROUTE} + labels: + glusterfs: deploy-heketi-${CLUSTER_NAME}-route + deploy-heketi: support + spec: + to: + kind: Service + name: deploy-heketi-${CLUSTER_NAME} +- kind: DeploymentConfig + apiVersion: v1 + metadata: + name: deploy-heketi-${CLUSTER_NAME} + labels: + glusterfs: deploy-heketi-${CLUSTER_NAME}-dc + deploy-heketi: support + annotations: + description: Defines how to deploy Heketi + spec: + replicas: 1 + selector: + glusterfs: deploy-heketi-${CLUSTER_NAME}-pod + triggers: + - type: ConfigChange + strategy: + type: Recreate + template: + metadata: + name: deploy-heketi + labels: + glusterfs: deploy-heketi-${CLUSTER_NAME}-pod + deploy-heketi: support + spec: + serviceAccountName: heketi-${CLUSTER_NAME}-service-account + containers: + - name: heketi + image: ${IMAGE_NAME}:${IMAGE_VERSION} + env: + - name: HEKETI_USER_KEY + value: ${HEKETI_USER_KEY} + - name: HEKETI_ADMIN_KEY + value: ${HEKETI_ADMIN_KEY} + - name: HEKETI_EXECUTOR + value: ${HEKETI_EXECUTOR} + - name: HEKETI_FSTAB + value: ${HEKETI_FSTAB} + - name: HEKETI_SNAPSHOT_LIMIT + value: '14' + - name: HEKETI_KUBE_GLUSTER_DAEMONSET + value: '1' + ports: + - containerPort: 8080 + volumeMounts: + - name: db + mountPath: /var/lib/heketi + - name: config + mountPath: /etc/heketi + readinessProbe: + timeoutSeconds: 3 + initialDelaySeconds: 3 + httpGet: + path: /hello + port: 8080 + livenessProbe: + timeoutSeconds: 3 + initialDelaySeconds: 30 + httpGet: + path: /hello + port: 8080 + volumes: + - name: db + - name: config + secret: + secretName: heketi-${CLUSTER_NAME}-config-secret +parameters: +- name: HEKETI_USER_KEY + displayName: Heketi User Secret + description: Set secret for those creating volumes as type _user_ +- name: HEKETI_ADMIN_KEY + displayName: Heketi Administrator Secret + description: Set secret for administration of the Heketi service as user _admin_ +- name: HEKETI_EXECUTOR + displayName: heketi executor type + description: Set the executor type, kubernetes or ssh + value: kubernetes +- name: HEKETI_FSTAB + displayName: heketi fstab path + description: Set the fstab path, file that is populated with bricks that heketi creates + value: /var/lib/heketi/fstab +- name: HEKETI_ROUTE + displayName: heketi route name + description: Set the hostname for the route URL + value: "heketi-glusterfs" +- name: IMAGE_NAME + displayName: heketi container image name + required: True +- name: IMAGE_VERSION + displayName: heketi container image version + required: True +- name: CLUSTER_NAME + displayName: GlusterFS cluster name + description: A unique name to identify this heketi service, useful for running multiple heketi instances + value: glusterfs diff --git a/roles/openshift_storage_glusterfs/files/v3.9/gluster-s3-pvcs-template.yml b/roles/openshift_storage_glusterfs/files/v3.9/gluster-s3-pvcs-template.yml new file mode 100644 index 000000000..064b51473 --- /dev/null +++ b/roles/openshift_storage_glusterfs/files/v3.9/gluster-s3-pvcs-template.yml @@ -0,0 +1,67 @@ +--- +kind: Template +apiVersion: v1 +metadata: + name: gluster-s3-pvcs + labels: + glusterfs: s3-pvcs-template + gluster-s3: pvcs-template + annotations: + description: Gluster S3 service template + tags: glusterfs,heketi,gluster-s3 +objects: +- kind: PersistentVolumeClaim + apiVersion: v1 + metadata: + name: "${PVC}" + labels: + glusterfs: s3-${CLUSTER_NAME}-${S3_ACCOUNT}-storage + gluster-s3: ${CLUSTER_NAME}-${S3_ACCOUNT}-pvc + annotations: + volume.beta.kubernetes.io/storage-class: "glusterfs-${CLUSTER_NAME}" + spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: "${PVC_SIZE}" +- kind: PersistentVolumeClaim + apiVersion: v1 + metadata: + name: "${META_PVC}" + labels: + glusterfs: s3-${CLUSTER_NAME}-${S3_ACCOUNT}-storage + gluster-s3: ${CLUSTER_NAME}-${S3_ACCOUNT}-meta-pvc + annotations: + volume.beta.kubernetes.io/storage-class: "glusterfs-${CLUSTER_NAME}" + spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: "${META_PVC_SIZE}" +parameters: +- name: S3_ACCOUNT + displayName: S3 Account Name + description: S3 storage account which will provide storage on GlusterFS volumes + required: true +- name: PVC + displayName: Primary GlusterFS-backed PVC + description: GlusterFS-backed PVC for object storage + required: true +- name: PVC_SIZE + displayName: Primary GlusterFS-backed PVC capacity + description: Capacity for GlusterFS-backed PVC for object storage + value: 2Gi +- name: META_PVC + displayName: Metadata GlusterFS-backed PVC + description: GlusterFS-backed PVC for object storage metadata + required: true +- name: META_PVC_SIZE + displayName: Metadata GlusterFS-backed PVC capacity + description: Capacity for GlusterFS-backed PVC for object storage metadata + value: 1Gi +- name: CLUSTER_NAME + displayName: GlusterFS cluster name + description: A unique name to identify which heketi service manages this cluster, useful for running multiple heketi instances + value: storage diff --git a/roles/openshift_storage_glusterfs/files/v3.9/gluster-s3-template.yml b/roles/openshift_storage_glusterfs/files/v3.9/gluster-s3-template.yml new file mode 100644 index 000000000..896a1b226 --- /dev/null +++ b/roles/openshift_storage_glusterfs/files/v3.9/gluster-s3-template.yml @@ -0,0 +1,140 @@ +--- +kind: Template +apiVersion: v1 +metadata: + name: gluster-s3 + labels: + glusterfs: s3-template + gluster-s3: template + annotations: + description: Gluster S3 service template + tags: glusterfs,heketi,gluster-s3 +objects: +- kind: Service + apiVersion: v1 + metadata: + name: gluster-s3-${CLUSTER_NAME}-${S3_ACCOUNT}-service + labels: + glusterfs: s3-${CLUSTER_NAME}-${S3_ACCOUNT}-service + gluster-s3: ${CLUSTER_NAME}-${S3_ACCOUNT}-service + spec: + ports: + - protocol: TCP + port: 8080 + targetPort: 8080 + selector: + glusterfs: s3-pod + type: ClusterIP + sessionAffinity: None + status: + loadBalancer: {} +- kind: Route + apiVersion: v1 + metadata: + name: gluster-s3-${CLUSTER_NAME}-${S3_ACCOUNT}-route + labels: + glusterfs: s3-${CLUSTER_NAME}-${S3_ACCOUNT}-route + gluster-s3: ${CLUSTER_NAME}-${S3_ACCOUNT}-route + spec: + to: + kind: Service + name: gluster-s3-${CLUSTER_NAME}-${S3_ACCOUNT}-service +- kind: DeploymentConfig + apiVersion: v1 + metadata: + name: gluster-s3-${CLUSTER_NAME}-${S3_ACCOUNT}-dc + labels: + glusterfs: s3-${CLUSTER_NAME}-${S3_ACCOUNT}-dc + gluster-s3: ${CLUSTER_NAME}-${S3_ACCOUNT}-dc + annotations: + openshift.io/scc: privileged + description: Defines how to deploy gluster s3 object storage + spec: + replicas: 1 + selector: + glusterfs: s3-${CLUSTER_NAME}-${S3_ACCOUNT}-pod + template: + metadata: + name: gluster-${CLUSTER_NAME}-${S3_ACCOUNT}-s3 + labels: + glusterfs: s3-${CLUSTER_NAME}-${S3_ACCOUNT}-pod + gluster-s3: ${CLUSTER_NAME}-${S3_ACCOUNT}-pod + spec: + containers: + - name: gluster-s3 + image: ${IMAGE_NAME}:${IMAGE_VERSION} + imagePullPolicy: IfNotPresent + ports: + - name: gluster + containerPort: 8080 + protocol: TCP + env: + - name: S3_ACCOUNT + value: "${S3_ACCOUNT}" + - name: S3_USER + value: "${S3_USER}" + - name: S3_PASSWORD + value: "${S3_PASSWORD}" + resources: {} + volumeMounts: + - name: gluster-vol1 + mountPath: "/mnt/gluster-object/${S3_ACCOUNT}" + - name: gluster-vol2 + mountPath: "/mnt/gluster-object/gsmetadata" + - name: glusterfs-cgroup + readOnly: true + mountPath: "/sys/fs/cgroup" + terminationMessagePath: "/dev/termination-log" + securityContext: + privileged: true + volumes: + - name: glusterfs-cgroup + hostPath: + path: "/sys/fs/cgroup" + - name: gluster-vol1 + persistentVolumeClaim: + claimName: ${PVC} + - name: gluster-vol2 + persistentVolumeClaim: + claimName: ${META_PVC} + restartPolicy: Always + terminationGracePeriodSeconds: 30 + dnsPolicy: ClusterFirst + serviceAccountName: default + serviceAccount: default + securityContext: {} +parameters: +- name: IMAGE_NAME + displayName: glusterblock provisioner container image name + required: True +- name: IMAGE_VERSION + displayName: glusterblock provisioner container image version + required: True +- name: CLUSTER_NAME + displayName: GlusterFS cluster name + description: A unique name to identify which heketi service manages this cluster, useful for running multiple heketi instances + value: storage +- name: S3_ACCOUNT + displayName: S3 Account Name + description: S3 storage account which will provide storage on GlusterFS volumes + required: true +- name: S3_USER + displayName: S3 User + description: S3 user who can access the S3 storage account + required: true +- name: S3_PASSWORD + displayName: S3 User Password + description: Password for the S3 user + required: true +- name: PVC + displayName: Primary GlusterFS-backed PVC + description: GlusterFS-backed PVC for object storage + value: gluster-s3-claim +- name: META_PVC + displayName: Metadata GlusterFS-backed PVC + description: GlusterFS-backed PVC for object storage metadata + value: gluster-s3-meta-claim +- name: CLUSTER_NAME + displayName: GlusterFS cluster name + description: A unique name to identify which heketi service manages this cluster, useful for running multiple heketi instances + value: storage diff --git a/roles/openshift_storage_glusterfs/files/v3.9/glusterblock-provisioner.yml b/roles/openshift_storage_glusterfs/files/v3.9/glusterblock-provisioner.yml new file mode 100644 index 000000000..63dd5cce6 --- /dev/null +++ b/roles/openshift_storage_glusterfs/files/v3.9/glusterblock-provisioner.yml @@ -0,0 +1,104 @@ +--- +kind: Template +apiVersion: v1 +metadata: + name: glusterblock-provisioner + labels: + glusterfs: block-template + glusterblock: template + annotations: + description: glusterblock provisioner template + tags: glusterfs +objects: +- kind: ClusterRole + apiVersion: v1 + metadata: + name: glusterblock-provisioner-runner + labels: + glusterfs: block-provisioner-runner-clusterrole + glusterblock: provisioner-runner-clusterrole + rules: + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch", "create", "delete"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: ["storage.k8s.io"] + resources: ["storageclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + - apiGroups: [""] + resources: ["services"] + verbs: ["get"] + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "create", "delete"] + - apiGroups: [""] + resources: ["routes"] + verbs: ["get", "list"] +- apiVersion: v1 + kind: ServiceAccount + metadata: + name: glusterblock-${CLUSTER_NAME}-provisioner + labels: + glusterfs: block-${CLUSTER_NAME}-provisioner-sa + glusterblock: ${CLUSTER_NAME}-provisioner-sa +- apiVersion: v1 + kind: ClusterRoleBinding + metadata: + name: glusterblock-${CLUSTER_NAME}-provisioner + roleRef: + name: glusterblock-provisioner-runner + subjects: + - kind: ServiceAccount + name: glusterblock-${CLUSTER_NAME}-provisioner + namespace: ${NAMESPACE} +- kind: DeploymentConfig + apiVersion: v1 + metadata: + name: glusterblock-${CLUSTER_NAME}-provisioner-dc + labels: + glusterfs: block-${CLUSTER_NAME}-provisioner-dc + glusterblock: ${CLUSTER_NAME}-provisioner-dc + annotations: + description: Defines how to deploy the glusterblock provisioner pod. + spec: + replicas: 1 + selector: + glusterfs: block-${CLUSTER_NAME}-provisioner-pod + triggers: + - type: ConfigChange + strategy: + type: Recreate + template: + metadata: + name: glusterblock-provisioner + labels: + glusterfs: block-${CLUSTER_NAME}-provisioner-pod + spec: + serviceAccountName: glusterblock-${CLUSTER_NAME}-provisioner + containers: + - name: glusterblock-provisioner + image: ${IMAGE_NAME}:${IMAGE_VERSION} + imagePullPolicy: IfNotPresent + env: + - name: PROVISIONER_NAME + value: gluster.org/glusterblock +parameters: +- name: IMAGE_NAME + displayName: glusterblock provisioner container image name + required: True +- name: IMAGE_VERSION + displayName: glusterblock provisioner container image version + required: True +- name: NAMESPACE + displayName: glusterblock provisioner namespace + description: The namespace in which these resources are being created + required: True +- name: CLUSTER_NAME + displayName: GlusterFS cluster name + description: A unique name to identify which heketi service manages this cluster, useful for running multiple heketi instances + value: storage diff --git a/roles/openshift_storage_glusterfs/files/v3.9/glusterfs-template.yml b/roles/openshift_storage_glusterfs/files/v3.9/glusterfs-template.yml new file mode 100644 index 000000000..09850a2c2 --- /dev/null +++ b/roles/openshift_storage_glusterfs/files/v3.9/glusterfs-template.yml @@ -0,0 +1,154 @@ +--- +kind: Template +apiVersion: v1 +metadata: + name: glusterfs + labels: + glusterfs: template + annotations: + description: GlusterFS DaemonSet template + tags: glusterfs +objects: +- kind: DaemonSet + apiVersion: extensions/v1beta1 + metadata: + name: glusterfs-${CLUSTER_NAME} + labels: + glusterfs: ${CLUSTER_NAME}-daemonset + annotations: + description: GlusterFS DaemonSet + tags: glusterfs + spec: + selector: + matchLabels: + glusterfs: ${CLUSTER_NAME}-pod + template: + metadata: + name: glusterfs-${CLUSTER_NAME} + labels: + glusterfs: ${CLUSTER_NAME}-pod + glusterfs-node: pod + spec: + nodeSelector: "${{NODE_LABELS}}" + hostNetwork: true + containers: + - name: glusterfs + image: ${IMAGE_NAME}:${IMAGE_VERSION} + imagePullPolicy: IfNotPresent + env: + - name: GB_GLFS_LRU_COUNT + value: "${GB_GLFS_LRU_COUNT}" + - name: TCMU_LOGDIR + value: "${TCMU_LOGDIR}" + resources: + requests: + memory: 100Mi + cpu: 100m + volumeMounts: + - name: glusterfs-heketi + mountPath: "/var/lib/heketi" + - name: glusterfs-run + mountPath: "/run" + - name: glusterfs-lvm + mountPath: "/run/lvm" + - name: glusterfs-etc + mountPath: "/etc/glusterfs" + - name: glusterfs-logs + mountPath: "/var/log/glusterfs" + - name: glusterfs-config + mountPath: "/var/lib/glusterd" + - name: glusterfs-dev + mountPath: "/dev" + - name: glusterfs-misc + mountPath: "/var/lib/misc/glusterfsd" + - name: glusterfs-cgroup + mountPath: "/sys/fs/cgroup" + readOnly: true + - name: glusterfs-ssl + mountPath: "/etc/ssl" + readOnly: true + securityContext: + capabilities: {} + privileged: true + readinessProbe: + timeoutSeconds: 3 + initialDelaySeconds: 40 + exec: + command: + - "/bin/bash" + - "-c" + - systemctl status glusterd.service + periodSeconds: 25 + successThreshold: 1 + failureThreshold: 15 + livenessProbe: + timeoutSeconds: 3 + initialDelaySeconds: 40 + exec: + command: + - "/bin/bash" + - "-c" + - systemctl status glusterd.service + periodSeconds: 25 + successThreshold: 1 + failureThreshold: 15 + terminationMessagePath: "/dev/termination-log" + volumes: + - name: glusterfs-heketi + hostPath: + path: "/var/lib/heketi" + - name: glusterfs-run + emptyDir: {} + - name: glusterfs-lvm + hostPath: + path: "/run/lvm" + - name: glusterfs-etc + hostPath: + path: "/etc/glusterfs" + - name: glusterfs-logs + hostPath: + path: "/var/log/glusterfs" + - name: glusterfs-config + hostPath: + path: "/var/lib/glusterd" + - name: glusterfs-dev + hostPath: + path: "/dev" + - name: glusterfs-misc + hostPath: + path: "/var/lib/misc/glusterfsd" + - name: glusterfs-cgroup + hostPath: + path: "/sys/fs/cgroup" + - name: glusterfs-ssl + hostPath: + path: "/etc/ssl" + restartPolicy: Always + terminationGracePeriodSeconds: 30 + dnsPolicy: ClusterFirst + securityContext: {} +parameters: +- name: NODE_LABELS + displayName: Daemonset Node Labels + description: Labels which define the daemonset node selector. Must contain at least one label of the format \'glusterfs=<CLUSTER_NAME>-host\' + value: '{ "glusterfs": "storage-host" }' +- name: IMAGE_NAME + displayName: GlusterFS container image name + required: True +- name: IMAGE_VERSION + displayName: GlusterFS container image version + required: True +- name: CLUSTER_NAME + displayName: GlusterFS cluster name + description: A unique name to identify which heketi service manages this cluster, useful for running multiple heketi instances + value: storage +- name: GB_GLFS_LRU_COUNT + displayName: Maximum number of block hosting volumes + description: This value is to set maximum number of block hosting volumes. + value: "15" + required: true +- name: TCMU_LOGDIR + displayName: Tcmu runner log directory + description: This value is to set tcmu runner log directory + value: "/var/log/glusterfs/gluster-block" + required: true diff --git a/roles/openshift_storage_glusterfs/files/v3.9/heketi-template.yml b/roles/openshift_storage_glusterfs/files/v3.9/heketi-template.yml new file mode 100644 index 000000000..28cdb2982 --- /dev/null +++ b/roles/openshift_storage_glusterfs/files/v3.9/heketi-template.yml @@ -0,0 +1,136 @@ +--- +kind: Template +apiVersion: v1 +metadata: + name: heketi + labels: + glusterfs: heketi-template + annotations: + description: Heketi service deployment template + tags: glusterfs,heketi +objects: +- kind: Service + apiVersion: v1 + metadata: + name: heketi-${CLUSTER_NAME} + labels: + glusterfs: heketi-${CLUSTER_NAME}-service + heketi: ${CLUSTER_NAME}-service + annotations: + description: Exposes Heketi service + spec: + ports: + - name: heketi + port: 8080 + targetPort: 8080 + selector: + glusterfs: heketi-${CLUSTER_NAME}-pod +- kind: Route + apiVersion: v1 + metadata: + name: ${HEKETI_ROUTE} + labels: + glusterfs: heketi-${CLUSTER_NAME}-route + heketi: ${CLUSTER_NAME}-route + spec: + to: + kind: Service + name: heketi-${CLUSTER_NAME} +- kind: DeploymentConfig + apiVersion: v1 + metadata: + name: heketi-${CLUSTER_NAME} + labels: + glusterfs: heketi-${CLUSTER_NAME}-dc + heketi: ${CLUSTER_NAME}-dc + annotations: + description: Defines how to deploy Heketi + spec: + replicas: 1 + selector: + glusterfs: heketi-${CLUSTER_NAME}-pod + triggers: + - type: ConfigChange + strategy: + type: Recreate + template: + metadata: + name: heketi-${CLUSTER_NAME} + labels: + glusterfs: heketi-${CLUSTER_NAME}-pod + heketi: ${CLUSTER_NAME}-pod + spec: + serviceAccountName: heketi-${CLUSTER_NAME}-service-account + containers: + - name: heketi + image: ${IMAGE_NAME}:${IMAGE_VERSION} + imagePullPolicy: IfNotPresent + env: + - name: HEKETI_USER_KEY + value: ${HEKETI_USER_KEY} + - name: HEKETI_ADMIN_KEY + value: ${HEKETI_ADMIN_KEY} + - name: HEKETI_EXECUTOR + value: ${HEKETI_EXECUTOR} + - name: HEKETI_FSTAB + value: ${HEKETI_FSTAB} + - name: HEKETI_SNAPSHOT_LIMIT + value: '14' + - name: HEKETI_KUBE_GLUSTER_DAEMONSET + value: '1' + ports: + - containerPort: 8080 + volumeMounts: + - name: db + mountPath: /var/lib/heketi + - name: config + mountPath: /etc/heketi + readinessProbe: + timeoutSeconds: 3 + initialDelaySeconds: 3 + httpGet: + path: /hello + port: 8080 + livenessProbe: + timeoutSeconds: 3 + initialDelaySeconds: 30 + httpGet: + path: /hello + port: 8080 + volumes: + - name: db + glusterfs: + endpoints: heketi-db-${CLUSTER_NAME}-endpoints + path: heketidbstorage + - name: config + secret: + secretName: heketi-${CLUSTER_NAME}-config-secret +parameters: +- name: HEKETI_USER_KEY + displayName: Heketi User Secret + description: Set secret for those creating volumes as type _user_ +- name: HEKETI_ADMIN_KEY + displayName: Heketi Administrator Secret + description: Set secret for administration of the Heketi service as user _admin_ +- name: HEKETI_EXECUTOR + displayName: heketi executor type + description: Set the executor type, kubernetes or ssh + value: kubernetes +- name: HEKETI_FSTAB + displayName: heketi fstab path + description: Set the fstab path, file that is populated with bricks that heketi creates + value: /var/lib/heketi/fstab +- name: HEKETI_ROUTE + displayName: heketi route name + description: Set the hostname for the route URL + value: "heketi-glusterfs" +- name: IMAGE_NAME + displayName: heketi container image name + required: True +- name: IMAGE_VERSION + displayName: heketi container image version + required: True +- name: CLUSTER_NAME + displayName: GlusterFS cluster name + description: A unique name to identify this heketi service, useful for running multiple heketi instances + value: glusterfs diff --git a/roles/openshift_storage_glusterfs/filter_plugins/openshift_storage_glusterfs.py b/roles/openshift_storage_glusterfs/filter_plugins/openshift_storage_glusterfs.py deleted file mode 100644 index a86c96df7..000000000 --- a/roles/openshift_storage_glusterfs/filter_plugins/openshift_storage_glusterfs.py +++ /dev/null @@ -1,23 +0,0 @@ -''' - Openshift Storage GlusterFS class that provides useful filters used in GlusterFS -''' - - -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(",")) - - -# pylint: disable=too-few-public-methods -class FilterModule(object): - ''' OpenShift Storage GlusterFS Filters ''' - - # pylint: disable=no-self-use, too-few-public-methods - def filters(self): - ''' Returns the names of the filters provided by this class ''' - return { - 'map_from_pairs': map_from_pairs - } diff --git a/roles/openshift_storage_glusterfs/tasks/glusterfs_config.yml b/roles/openshift_storage_glusterfs/tasks/glusterfs_config.yml index 2ea7286f3..a374df0ce 100644 --- a/roles/openshift_storage_glusterfs/tasks/glusterfs_config.yml +++ b/roles/openshift_storage_glusterfs/tasks/glusterfs_config.yml @@ -4,6 +4,7 @@ glusterfs_namespace: "{{ openshift_storage_glusterfs_namespace }}" glusterfs_is_native: "{{ openshift_storage_glusterfs_is_native | bool }}" glusterfs_name: "{{ openshift_storage_glusterfs_name }}" + # map_from_pairs is a custom filter plugin in role lib_utils glusterfs_nodeselector: "{{ openshift_storage_glusterfs_nodeselector | default(['storagenode', openshift_storage_glusterfs_name] | join('=')) | map_from_pairs }}" glusterfs_use_default_selector: "{{ openshift_storage_glusterfs_use_default_selector }}" glusterfs_storageclass: "{{ openshift_storage_glusterfs_storageclass }}" diff --git a/roles/openshift_storage_glusterfs/tasks/glusterfs_registry.yml b/roles/openshift_storage_glusterfs/tasks/glusterfs_registry.yml index b7cff6514..544a6f491 100644 --- a/roles/openshift_storage_glusterfs/tasks/glusterfs_registry.yml +++ b/roles/openshift_storage_glusterfs/tasks/glusterfs_registry.yml @@ -4,6 +4,7 @@ glusterfs_namespace: "{{ openshift_storage_glusterfs_registry_namespace }}" glusterfs_is_native: "{{ openshift_storage_glusterfs_registry_is_native | bool }}" glusterfs_name: "{{ openshift_storage_glusterfs_registry_name }}" + # map_from_pairs is a custom filter plugin in role lib_utils glusterfs_nodeselector: "{{ openshift_storage_glusterfs_registry_nodeselector | default(['storagenode', openshift_storage_glusterfs_registry_name] | join('=')) | map_from_pairs }}" glusterfs_use_default_selector: "{{ openshift_storage_glusterfs_registry_use_default_selector }}" glusterfs_storageclass: "{{ openshift_storage_glusterfs_registry_storageclass }}" diff --git a/roles/openshift_version/tasks/check_available_rpms.yml b/roles/openshift_version/tasks/check_available_rpms.yml index bdbc63d27..fea0daf77 100644 --- a/roles/openshift_version/tasks/check_available_rpms.yml +++ b/roles/openshift_version/tasks/check_available_rpms.yml @@ -1,7 +1,7 @@ --- - name: Get available {{ openshift_service_type}} version repoquery: - name: "{{ openshift_service_type}}" + name: "{{ openshift_service_type}}{{ '-' ~ openshift_release ~ '*' if openshift_release is defined else '' }}" ignore_excluders: true register: rpm_results diff --git a/roles/openshift_version/tasks/first_master_containerized_version.yml b/roles/openshift_version/tasks/first_master_containerized_version.yml index e02a75eab..3ed1d2cfe 100644 --- a/roles/openshift_version/tasks/first_master_containerized_version.yml +++ b/roles/openshift_version/tasks/first_master_containerized_version.yml @@ -7,6 +7,7 @@ when: - openshift_image_tag is defined - openshift_version is not defined + - not (openshift_version_reinit | default(false)) - name: Set containerized version to configure if openshift_release specified set_fact: @@ -20,7 +21,7 @@ docker run --rm {{ openshift_cli_image }}:latest version register: cli_image_version when: - - openshift_version is not defined + - openshift_version is not defined or openshift_version_reinit | default(false) - not openshift_use_crio_only # Origin latest = pre-release version (i.e. v1.3.0-alpha.1-321-gb095e3a) @@ -34,7 +35,7 @@ - set_fact: openshift_version: "{{ cli_image_version.stdout_lines[0].split(' ')[1].split('-')[0][1:] }}" - when: openshift_version is not defined + when: openshift_version is not defined or openshift_version_reinit | default(false) # If we got an openshift_version like "3.2", lookup the latest 3.2 container version # and use that value instead. diff --git a/roles/openshift_version/tasks/first_master_rpm_version.yml b/roles/openshift_version/tasks/first_master_rpm_version.yml index 264baca65..5d92f90c6 100644 --- a/roles/openshift_version/tasks/first_master_rpm_version.yml +++ b/roles/openshift_version/tasks/first_master_rpm_version.yml @@ -6,6 +6,7 @@ when: - openshift_pkg_version is defined - openshift_version is not defined + - not (openshift_version_reinit | default(false)) # These tasks should only be run against masters and nodes - name: Set openshift_version for rpm installation @@ -13,4 +14,7 @@ - set_fact: openshift_version: "{{ rpm_results.results.versions.available_versions.0 }}" - when: openshift_version is not defined + when: openshift_version is not defined or ( openshift_version_reinit | default(false) ) +- set_fact: + openshift_pkg_version: "-{{ rpm_results.results.versions.available_versions.0 }}" + when: openshift_version_reinit | default(false) diff --git a/roles/openshift_version/tasks/masters_and_nodes.yml b/roles/openshift_version/tasks/masters_and_nodes.yml index fbeb22d8b..eddd5ff42 100644 --- a/roles/openshift_version/tasks/masters_and_nodes.yml +++ b/roles/openshift_version/tasks/masters_and_nodes.yml @@ -6,9 +6,12 @@ include_tasks: check_available_rpms.yml - name: Fail if rpm version and docker image version are different fail: - msg: "OCP rpm version {{ openshift_rpm_version }} is different from OCP image version {{ openshift_version }}" + msg: "OCP rpm version {{ rpm_results.results.versions.available_versions.0 }} is different from OCP image version {{ openshift_version }}" # Both versions have the same string representation - when: rpm_results.results.versions.available_versions.0 != openshift_version + when: + - openshift_version not in rpm_results.results.versions.available_versions.0 + - openshift_version_reinit | default(false) + # block when when: not openshift_is_atomic | bool diff --git a/roles/openshift_web_console/defaults/main.yml b/roles/openshift_web_console/defaults/main.yml index 4f395398c..c747f73a8 100644 --- a/roles/openshift_web_console/defaults/main.yml +++ b/roles/openshift_web_console/defaults/main.yml @@ -1,3 +1,2 @@ --- -# TODO: This is temporary and will be updated to use taints and tolerations so that the console runs on the masters -openshift_web_console_nodeselector: {"region":"infra"} +openshift_web_console_nodeselector: "{{ openshift_hosted_infra_selector | default('region=infra') | map_from_pairs }}" diff --git a/roles/openshift_web_console/tasks/install.yml b/roles/openshift_web_console/tasks/install.yml index 8ee95e36b..ead62799a 100644 --- a/roles/openshift_web_console/tasks/install.yml +++ b/roles/openshift_web_console/tasks/install.yml @@ -18,44 +18,124 @@ oc_project: name: openshift-web-console state: present + node_selector: + - "" -- name: Make temp directory for asset config files +- name: Make temp directory for web console templates command: mktemp -d /tmp/console-ansible-XXXXXX register: mktemp changed_when: False -- name: Copy asset config template to temp directory +- name: Copy admin client config + command: > + cp {{ openshift.common.config_base }}/master//admin.kubeconfig {{ mktemp.stdout }}/admin.kubeconfig + changed_when: false + +- name: Copy web console templates to temp directory copy: src: "{{ __console_files_location }}/{{ item }}" dest: "{{ mktemp.stdout }}/{{ item }}" with_items: - "{{ __console_template_file }}" + - "{{ __console_rbac_file }}" - "{{ __console_config_file }}" -- name: Update asset config properties - yedit: - src: "{{ mktemp.stdout }}/{{ __console_config_file }}" - edits: - - key: logoutURL - value: "{{ openshift.master.logout_url | default('') }}" - - key: publicURL - # Must have a trailing slash - value: "{{ openshift.master.public_console_url }}/" - - key: masterPublicURL - value: "{{ openshift.master.public_api_url }}" +# Check if an existing webconsole-config config map exists. If so, use those +# contents so we don't overwrite changes. +- name: Read the existing web console config map + oc_configmap: + namespace: openshift-web-console + name: webconsole-config + state: list + register: webconsole_config_map + +- set_fact: + existing_config_map_data: "{{ webconsole_config_map.results.results[0].data | default({}) }}" + +- name: Copy the existing web console config to temp directory + copy: + content: "{{ existing_config_map_data['webconsole-config.yaml'] }}" + dest: "{{ mktemp.stdout }}/{{ __console_config_file }}" + when: existing_config_map_data['webconsole-config.yaml'] is defined + +# Generate a new config when a config map is not defined. +- when: existing_config_map_data['webconsole-config.yaml'] is not defined + block: + # Migrate the previous master-config.yaml asset config if it exists into the new + # web console config config map. + - name: Read existing assetConfig in master-config.yaml + slurp: + src: "{{ openshift.common.config_base }}/master/master-config.yaml" + register: master_config_output + + - set_fact: + config_to_migrate: "{{ master_config_output.content | b64decode | from_yaml }}" + + # Update properties in the config template based on inventory vars when the + # asset config does not exist. + - name: Set web console config properties from inventory variables + yedit: + src: "{{ mktemp.stdout }}/{{ __console_config_file }}" + edits: + - key: clusterInfo#consolePublicURL + # Must have a trailing slash + value: "{{ openshift.master.public_console_url }}/" + - key: clusterInfo#masterPublicURL + value: "{{ openshift.master.public_api_url }}" + - key: clusterInfo#logoutPublicURL + value: "{{ openshift.master.logout_url | default('') }}" + - key: features#inactivityTimeoutMinutes + value: "{{ openshift_web_console_inactivity_timeout_minutes | default(0) }}" + - key: extensions#scriptURLs + value: "{{ openshift_web_console_extension_script_urls | default([]) }}" + - key: extensions#stylesheetURLs + value: "{{ openshift_web_console_extension_stylesheet_urls | default([]) }}" + - key: extensions#properties + value: "{{ openshift_web_console_extension_properties | default({}) }}" + separator: '#' + state: present + when: config_to_migrate.assetConfig is not defined + + - name: Migrate assetConfig from master-config.yaml + yedit: + src: "{{ mktemp.stdout }}/{{ __console_config_file }}" + edits: + - key: clusterInfo#consolePublicURL + value: "{{ config_to_migrate.assetConfig.publicURL }}" + - key: clusterInfo#masterPublicURL + value: "{{ config_to_migrate.assetConfig.masterPublicURL }}" + - key: clusterInfo#logoutPublicURL + value: "{{ config_to_migrate.assetConfig.logoutURL | default('') }}" + - key: clusterInfo#metricsPublicURL + value: "{{ config_to_migrate.assetConfig.metricsPublicURL | default('') }}" + - key: clusterInfo#loggingPublicURL + value: "{{ config_to_migrate.assetConfig.loggingPublicURL | default('') }}" + - key: servingInfo#maxRequestsInFlight + value: "{{ config_to_migrate.assetConfig.servingInfo.maxRequestsInFlight | default(0) }}" + - key: servingInfo#requestTimeoutSeconds + value: "{{ config_to_migrate.assetConfig.servingInfo.requestTimeoutSeconds | default(0) }}" + separator: '#' + state: present + when: config_to_migrate.assetConfig is defined - slurp: src: "{{ mktemp.stdout }}/{{ __console_config_file }}" - register: config + register: updated_console_config + +- name: Reconcile with the web console RBAC file + shell: > + {{ openshift_client_binary }} process -f "{{ mktemp.stdout }}/{{ __console_rbac_file }}" --config={{ mktemp.stdout }}/admin.kubeconfig + | {{ openshift_client_binary }} auth reconcile --config={{ mktemp.stdout }}/admin.kubeconfig -f - -- name: Apply template file +- name: Apply the web console template file shell: > {{ openshift_client_binary }} process -f "{{ mktemp.stdout }}/{{ __console_template_file }}" - --param API_SERVER_CONFIG="{{ config['content'] | b64decode }}" + --param API_SERVER_CONFIG="{{ updated_console_config['content'] | b64decode }}" --param IMAGE="{{ openshift_web_console_prefix }}{{ openshift_web_console_image_name }}:{{ openshift_web_console_version }}" --param NODE_SELECTOR={{ openshift_web_console_nodeselector | to_json | quote }} --param REPLICA_COUNT="{{ openshift_web_console_replica_count }}" - | {{ openshift_client_binary }} apply -f - + --config={{ mktemp.stdout }}/admin.kubeconfig + | {{ openshift_client_binary }} apply --config={{ mktemp.stdout }}/admin.kubeconfig -f - - name: Verify that the web console is running command: > diff --git a/roles/openshift_web_console/tasks/rollout_console.yml b/roles/openshift_web_console/tasks/rollout_console.yml new file mode 100644 index 000000000..75682ba1d --- /dev/null +++ b/roles/openshift_web_console/tasks/rollout_console.yml @@ -0,0 +1,20 @@ +--- +- name: Check if console deployment exists + oc_obj: + kind: deployments + name: webconsole + namespace: openshift-web-console + state: list + register: console_deployment + +# There's currently no command to trigger a rollout for a k8s deployment +# without changing the pod spec. Add an annotation to force a rollout. +- name: Rollout updated web console deployment + oc_edit: + kind: deployments + name: webconsole + namespace: openshift-web-console + separator: '#' + content: + spec#template#metadata#annotations#installer-triggered-rollout: "{{ ansible_date_time.iso8601_micro }}" + when: console_deployment.results.results.0 | length > 0 diff --git a/roles/openshift_web_console/tasks/update_asset_config.yml b/roles/openshift_web_console/tasks/update_asset_config.yml deleted file mode 100644 index 0992b32e1..000000000 --- a/roles/openshift_web_console/tasks/update_asset_config.yml +++ /dev/null @@ -1,68 +0,0 @@ ---- -# This task updates asset config values in the webconsole-config config map in -# the openshift-web-console namespace. The values to set are pased in the -# variable `asset_config_edits`, which is an array of objects with `key` and -# `value` properties in the same format as `yedit` module `edits`. Only -# properties passed are updated. -# -# Note that this triggers a redeployment on the console and a brief downtime -# since it uses a `Recreate` strategy. -# -# Example usage: -# -# - include_role: -# name: openshift_web_console -# tasks_from: update_asset_config.yml -# vars: -# asset_config_edits: -# - key: loggingPublicURL -# value: "https://{{ openshift_logging_kibana_hostname }}" -# when: openshift_web_console_install | default(true) | bool - -- name: Read web console config map - oc_configmap: - namespace: openshift-web-console - name: webconsole-config - state: list - register: webconsole_config - -- name: Make temp directory - command: mktemp -d /tmp/console-ansible-XXXXXX - register: mktemp - changed_when: False - -- name: Copy asset config to temp file - copy: - content: "{{webconsole_config.results.results[0].data['webconsole-config.yaml']}}" - dest: "{{ mktemp.stdout }}/webconsole-config.yaml" - -- name: Change asset config properties - yedit: - src: "{{ mktemp.stdout }}/webconsole-config.yaml" - edits: "{{asset_config_edits}}" - -- name: Update web console config map - oc_configmap: - namespace: openshift-web-console - name: webconsole-config - state: present - from_file: - webconsole-config.yaml: "{{ mktemp.stdout }}/webconsole-config.yaml" - -- name: Remove temp directory - file: - state: absent - name: "{{ mktemp.stdout }}" - changed_when: False - -# There's currently no command to trigger a rollout for a k8s deployment -# without changing the pod spec. Add an annotation to force a rollout after -# the config map has been edited. -- name: Rollout updated web console deployment - oc_edit: - kind: deployments - name: webconsole - namespace: openshift-web-console - separator: '#' - content: - spec#template#metadata#annotations#installer-triggered-rollout: "{{ ansible_date_time.iso8601_micro }}" diff --git a/roles/openshift_web_console/tasks/update_console_config.yml b/roles/openshift_web_console/tasks/update_console_config.yml new file mode 100644 index 000000000..41da2c16a --- /dev/null +++ b/roles/openshift_web_console/tasks/update_console_config.yml @@ -0,0 +1,66 @@ +--- +# This task updates asset config values in the webconsole-config config map in +# the openshift-web-console namespace. The values to set are pased in the +# variable `console_config_edits`, which is an array of objects with `key` and +# `value` properties in the same format as `yedit` module `edits`. Only +# properties passed are updated. The separator for nested properties is `#`. +# +# Note that this triggers a redeployment on the console and a brief downtime +# since it uses a `Recreate` strategy. +# +# Example usage: +# +# - include_role: +# name: openshift_web_console +# tasks_from: update_console_config.yml +# vars: +# console_config_edits: +# - key: clusterInfo#loggingPublicURL +# value: "https://{{ openshift_logging_kibana_hostname }}" +# when: openshift_web_console_install | default(true) | bool + +- name: Read the existing web console config map + oc_configmap: + namespace: openshift-web-console + name: webconsole-config + state: list + register: webconsole_config_map + +- set_fact: + existing_config_map_data: "{{ webconsole_config_map.results.results[0].data | default({}) }}" + +- when: existing_config_map_data['webconsole-config.yaml'] is defined + block: + - name: Make temp directory + command: mktemp -d /tmp/console-ansible-XXXXXX + register: mktemp_console + changed_when: False + + - name: Copy the existing web console config to temp directory + copy: + content: "{{ existing_config_map_data['webconsole-config.yaml'] }}" + dest: "{{ mktemp_console.stdout }}/webconsole-config.yaml" + + - name: Change web console config properties + yedit: + src: "{{ mktemp_console.stdout }}/webconsole-config.yaml" + edits: "{{console_config_edits}}" + separator: '#' + state: present + + - name: Update web console config map + oc_configmap: + namespace: openshift-web-console + name: webconsole-config + state: present + from_file: + webconsole-config.yaml: "{{ mktemp_console.stdout }}/webconsole-config.yaml" + + - name: Remove temp directory + file: + state: absent + name: "{{ mktemp_console.stdout }}" + changed_when: False + + # TODO: Only rollout if config has changed. + - include_tasks: rollout_console.yml diff --git a/roles/openshift_web_console/vars/default_images.yml b/roles/openshift_web_console/vars/default_images.yml index 7adb8a0d0..42d331ac5 100644 --- a/roles/openshift_web_console/vars/default_images.yml +++ b/roles/openshift_web_console/vars/default_images.yml @@ -1,4 +1,4 @@ --- -__openshift_web_console_prefix: "docker.io/openshift/" +__openshift_web_console_prefix: "docker.io/openshift/origin-" __openshift_web_console_version: "latest" -__openshift_web_console_image_name: "origin-web-console" +__openshift_web_console_image_name: "web-console" diff --git a/roles/openshift_web_console/vars/main.yml b/roles/openshift_web_console/vars/main.yml index 80bc56a17..e91048e38 100644 --- a/roles/openshift_web_console/vars/main.yml +++ b/roles/openshift_web_console/vars/main.yml @@ -2,4 +2,5 @@ __console_files_location: "../../../files/origin-components/" __console_template_file: "console-template.yaml" +__console_rbac_file: "console-rbac-template.yaml" __console_config_file: "console-config.yaml" diff --git a/roles/openshift_web_console/vars/openshift-enterprise.yml b/roles/openshift_web_console/vars/openshift-enterprise.yml index 721ac1d27..375c22067 100644 --- a/roles/openshift_web_console/vars/openshift-enterprise.yml +++ b/roles/openshift_web_console/vars/openshift-enterprise.yml @@ -1,4 +1,4 @@ --- -__openshift_web_console_prefix: "registry.access.redhat.com/openshift3/" +__openshift_web_console_prefix: "registry.access.redhat.com/openshift3/ose-" __openshift_web_console_version: "v3.9" -__openshift_web_console_image_name: "ose-web-console" +__openshift_web_console_image_name: "web-console" diff --git a/roles/os_firewall/tasks/firewalld.yml b/roles/os_firewall/tasks/firewalld.yml index 4eae31596..fa933da51 100644 --- a/roles/os_firewall/tasks/firewalld.yml +++ b/roles/os_firewall/tasks/firewalld.yml @@ -2,7 +2,9 @@ - name: Fail - Firewalld is not supported on Atomic Host fail: msg: "Firewalld is not supported on Atomic Host" - when: r_os_firewall_is_atomic | bool + when: + - r_os_firewall_is_atomic | bool + - not openshift_enable_unsupported_configurations | default(false) - name: Install firewalld packages package: @@ -10,6 +12,7 @@ state: present register: result until: result is succeeded + when: not r_os_firewall_is_atomic | bool - name: Ensure iptables services are not enabled systemd: diff --git a/roles/template_service_broker/defaults/main.yml b/roles/template_service_broker/defaults/main.yml index c32872d24..3465832cc 100644 --- a/roles/template_service_broker/defaults/main.yml +++ b/roles/template_service_broker/defaults/main.yml @@ -3,4 +3,4 @@ template_service_broker_remove: False template_service_broker_install: True openshift_template_service_broker_namespaces: ['openshift'] -template_service_broker_selector: { "region": "infra" } +template_service_broker_selector: "{{ openshift_hosted_infra_selector | default('region=infra') | map_from_pairs }}" diff --git a/roles/template_service_broker/tasks/install.yml b/roles/template_service_broker/tasks/install.yml index 604e94602..4e6ad2ae5 100644 --- a/roles/template_service_broker/tasks/install.yml +++ b/roles/template_service_broker/tasks/install.yml @@ -22,6 +22,11 @@ register: mktemp changed_when: False +- name: Copy admin client config + command: > + cp {{ openshift.common.config_base }}/master//admin.kubeconfig {{ mktemp.stdout }}/admin.kubeconfig + changed_when: false + - copy: src: "{{ __tsb_files_location }}/{{ item }}" dest: "{{ mktemp.stdout }}/{{ item }}" @@ -43,16 +48,18 @@ - name: Apply template file shell: > - {{ openshift_client_binary }} process -f "{{ mktemp.stdout }}/{{ __tsb_template_file }}" + {{ openshift_client_binary }} process --config={{ mktemp.stdout }}/admin.kubeconfig + -f "{{ mktemp.stdout }}/{{ __tsb_template_file }}" --param API_SERVER_CONFIG="{{ config['content'] | b64decode }}" --param IMAGE="{{ template_service_broker_prefix }}{{ template_service_broker_image_name }}:{{ template_service_broker_version }}" --param NODE_SELECTOR={{ template_service_broker_selector | to_json | quote }} - | {{ openshift_client_binary }} apply -f - + | {{ openshift_client_binary }} apply --config={{ mktemp.stdout }}/admin.kubeconfig -f - # reconcile with rbac - name: Reconcile with RBAC file shell: > - {{ openshift_client_binary }} process -f "{{ mktemp.stdout }}/{{ __tsb_rbac_file }}" | {{ openshift_client_binary }} auth reconcile -f - + {{ openshift_client_binary }} process --config={{ mktemp.stdout }}/admin.kubeconfig -f "{{ mktemp.stdout }}/{{ __tsb_rbac_file }}" + | {{ openshift_client_binary }} auth reconcile --config={{ mktemp.stdout }}/admin.kubeconfig -f - # Check that the TSB is running - name: Verify that TSB is running @@ -79,9 +86,15 @@ # Register with broker - name: Register TSB with broker shell: > - {{ openshift_client_binary }} process -f "{{ mktemp.stdout }}/{{ __tsb_broker_file }}" --param CA_BUNDLE="{{ __ca_bundle.content }}" | {{ openshift_client_binary }} apply -f - + {{ openshift_client_binary }} process --config={{ mktemp.stdout }}/admin.kubeconfig -f "{{ mktemp.stdout }}/{{ __tsb_broker_file }}" --param CA_BUNDLE="{{ __ca_bundle.content }}" | {{ openshift_client_binary }} apply --config={{ mktemp.stdout }}/admin.kubeconfig -f - - file: state: absent name: "{{ mktemp.stdout }}" changed_when: False + +- name: Rollout console so it discovers the template service broker is installed + include_role: + name: openshift_web_console + tasks_from: rollout_console.yml + when: openshift_web_console_install | default(true) | bool diff --git a/roles/template_service_broker/tasks/remove.yml b/roles/template_service_broker/tasks/remove.yml index db1b558e4..48dc1327e 100644 --- a/roles/template_service_broker/tasks/remove.yml +++ b/roles/template_service_broker/tasks/remove.yml @@ -3,6 +3,11 @@ register: mktemp changed_when: False +- name: Copy admin client config + command: > + cp {{ openshift.common.config_base }}/master//admin.kubeconfig {{ mktemp.stdout }}/admin.kubeconfig + changed_when: false + - copy: src: "{{ __tsb_files_location }}/{{ item }}" dest: "{{ mktemp.stdout }}/{{ item }}" @@ -12,11 +17,11 @@ - name: Delete TSB broker shell: > - {{ openshift_client_binary }} process -f "{{ mktemp.stdout }}/{{ __tsb_broker_file }}" | {{ openshift_client_binary }} delete --ignore-not-found -f - + {{ openshift_client_binary }} process --config={{ mktemp.stdout }}/admin.kubeconfig -f "{{ mktemp.stdout }}/{{ __tsb_broker_file }}" | {{ openshift_client_binary }} delete --config={{ mktemp.stdout }}/admin.kubeconfig --ignore-not-found -f - - name: Delete TSB objects shell: > - {{ openshift_client_binary }} process -f "{{ mktemp.stdout }}/{{ __tsb_template_file }}" | {{ openshift_client_binary }} delete --ignore-not-found -f - + {{ openshift_client_binary }} process --config={{ mktemp.stdout }}/admin.kubeconfig -f "{{ mktemp.stdout }}/{{ __tsb_template_file }}" | {{ openshift_client_binary }} delete --config={{ mktemp.stdout }}/admin.kubeconfig --ignore-not-found -f - - name: empty out tech preview extension file for service console UI copy: @@ -31,3 +36,9 @@ state: absent name: "{{ mktemp.stdout }}" changed_when: False + +- name: Rollout console so it discovers the template service broker is removed + include_role: + name: openshift_web_console + tasks_from: rollout_console.yml + when: openshift_web_console_install | default(true) | bool diff --git a/roles/template_service_broker/vars/default_images.yml b/roles/template_service_broker/vars/default_images.yml index 77afe1f43..dc164a4db 100644 --- a/roles/template_service_broker/vars/default_images.yml +++ b/roles/template_service_broker/vars/default_images.yml @@ -1,4 +1,4 @@ --- -__template_service_broker_prefix: "docker.io/openshift/" +__template_service_broker_prefix: "docker.io/openshift/origin-" __template_service_broker_version: "latest" -__template_service_broker_image_name: "origin" +__template_service_broker_image_name: "template-service-broker" diff --git a/roles/template_service_broker/vars/openshift-enterprise.yml b/roles/template_service_broker/vars/openshift-enterprise.yml index dfab1e01b..b65b97691 100644 --- a/roles/template_service_broker/vars/openshift-enterprise.yml +++ b/roles/template_service_broker/vars/openshift-enterprise.yml @@ -1,4 +1,4 @@ --- -__template_service_broker_prefix: "registry.access.redhat.com/openshift3/" +__template_service_broker_prefix: "registry.access.redhat.com/openshift3/ose-" __template_service_broker_version: "v3.7" -__template_service_broker_image_name: "ose" +__template_service_broker_image_name: "template-service-broker" diff --git a/roles/tuned/tasks/main.yml b/roles/tuned/tasks/main.yml index 4a28d47b2..5129f4471 100644 --- a/roles/tuned/tasks/main.yml +++ b/roles/tuned/tasks/main.yml @@ -28,7 +28,12 @@ when: item.state == 'file' - name: Make tuned use the recommended tuned profile on restart - file: path=/etc/tuned/active_profile state=absent + file: + path: '{{ item }}' + state: absent + with_items: + - /etc/tuned/active_profile + - /etc/tuned/profile_mode - name: Restart tuned service systemd: diff --git a/utils/src/ooinstall/ansible_plugins/facts_callback.py b/utils/src/ooinstall/ansible_plugins/facts_callback.py index 433e29dde..6251cd22b 100644 --- a/utils/src/ooinstall/ansible_plugins/facts_callback.py +++ b/utils/src/ooinstall/ansible_plugins/facts_callback.py @@ -7,11 +7,7 @@ import yaml from ansible.plugins.callback import CallbackBase from ansible.parsing.yaml.dumper import AnsibleDumper -# ansible.compat.six goes away with Ansible 2.4 -try: - from ansible.compat.six import u -except ImportError: - from ansible.module_utils.six import u +from ansible.module_utils.six import u # pylint: disable=super-init-not-called diff --git a/utils/src/ooinstall/cli_installer.py b/utils/src/ooinstall/cli_installer.py index 1226242d0..a85a43bd3 100644 --- a/utils/src/ooinstall/cli_installer.py +++ b/utils/src/ooinstall/cli_installer.py @@ -938,91 +938,10 @@ def uninstall(ctx): @click.pass_context # pylint: disable=too-many-statements,too-many-branches def upgrade(ctx, latest_minor, next_major): - oo_cfg = ctx.obj['oo_cfg'] - - if len(oo_cfg.deployment.hosts) == 0: - click.echo("No hosts defined in: %s" % oo_cfg.config_path) - sys.exit(1) - - variant = oo_cfg.settings['variant'] - if find_variant(variant)[0] is None: - click.echo("%s is not a supported variant for upgrade." % variant) - sys.exit(0) - - old_version = oo_cfg.settings['variant_version'] - - try: - mapping = UPGRADE_MAPPINGS[old_version] - except KeyError: - click.echo('No upgrades available for %s %s' % (variant, old_version)) - sys.exit(0) - - message = """ - This tool will help you upgrade your existing OpenShift installation. - Currently running: %s %s -""" - click.echo(message % (variant, old_version)) - - # Map the dynamic upgrade options to the playbook to run for each. - # Index offset by 1. - # List contains tuples of booleans for (latest_minor, next_major) - selections = [] - if not (latest_minor or next_major): - i = 0 - if 'minor_playbook' in mapping: - click.echo("(%s) Update to latest %s" % (i + 1, old_version)) - selections.append((True, False)) - i += 1 - if 'major_playbook' in mapping: - click.echo("(%s) Upgrade to next release: %s" % (i + 1, mapping['major_version'])) - selections.append((False, True)) - i += 1 - - response = click.prompt("\nChoose an option from above", - type=click.Choice(list(map(str, range(1, len(selections) + 1))))) - latest_minor, next_major = selections[int(response) - 1] - - if next_major: - if 'major_playbook' not in mapping: - click.echo("No major upgrade supported for %s %s with this version " - "of atomic-openshift-utils." % (variant, old_version)) - sys.exit(0) - playbook = mapping['major_playbook'] - new_version = mapping['major_version'] - # Update config to reflect the version we're targeting, we'll write - # to disk once Ansible completes successfully, not before. - oo_cfg.settings['variant_version'] = new_version - if oo_cfg.settings['variant'] == 'enterprise': - oo_cfg.settings['variant'] = 'openshift-enterprise' - - if latest_minor: - if 'minor_playbook' not in mapping: - click.echo("No minor upgrade supported for %s %s with this version " - "of atomic-openshift-utils." % (variant, old_version)) - sys.exit(0) - playbook = mapping['minor_playbook'] - new_version = old_version - - click.echo("OpenShift will be upgraded from %s %s to latest %s %s on the following hosts:\n" % ( - variant, old_version, oo_cfg.settings['variant'], new_version)) - for host in oo_cfg.deployment.hosts: - click.echo(" * %s" % host.connect_to) - - if not ctx.obj['unattended']: - # Prompt interactively to confirm: - if not click.confirm("\nDo you want to proceed?"): - click.echo("Upgrade cancelled.") - sys.exit(0) - - retcode = openshift_ansible.run_upgrade_playbook(oo_cfg.deployment.hosts, - playbook, - ctx.obj['verbose']) - if retcode > 0: - click.echo("Errors encountered during upgrade, please check %s." % - oo_cfg.settings['ansible_log_path']) - else: - oo_cfg.save_to_disk() - click.echo("Upgrade completed! Rebooting all hosts is recommended.") + click.echo("Upgrades are no longer supported by this version of installer") + click.echo("Please see the documentation for manual upgrade:") + click.echo("https://docs.openshift.com/container-platform/latest/install_config/upgrading/automated_upgrades.html") + sys.exit(1) @click.command() diff --git a/utils/src/ooinstall/openshift_ansible.py b/utils/src/ooinstall/openshift_ansible.py index dda8eb4c6..84a76fa53 100644 --- a/utils/src/ooinstall/openshift_ansible.py +++ b/utils/src/ooinstall/openshift_ansible.py @@ -122,7 +122,7 @@ def write_inventory_vars(base_inventory, lb): if CFG.deployment.variables['ansible_ssh_user'] != 'root': base_inventory.write('ansible_become=yes\n') - base_inventory.write('openshift_override_hostname_check=true\n') + base_inventory.write('openshift_hostname_check=false\n') if lb is not None: base_inventory.write("openshift_master_cluster_hostname={}\n".format(lb.hostname)) @@ -321,21 +321,3 @@ def run_uninstall_playbook(hosts, verbose=False): facts_env['ANSIBLE_CONFIG'] = CFG.settings['ansible_quiet_config'] return run_ansible(playbook, inventory_file, facts_env, verbose) - - -def run_upgrade_playbook(hosts, playbook, verbose=False): - playbook = os.path.join(CFG.settings['ansible_playbook_directory'], - 'playbooks/byo/openshift-cluster/upgrades/{}'.format(playbook)) - - # TODO: Upgrade inventory for upgrade? - inventory_file = generate_inventory(hosts) - facts_env = os.environ.copy() - if 'ansible_log_path' in CFG.settings: - facts_env['ANSIBLE_LOG_PATH'] = CFG.settings['ansible_log_path'] - if 'ansible_config' in CFG.settings: - facts_env['ANSIBLE_CONFIG'] = CFG.settings['ansible_config'] - # override the ansible config for our main playbook run - if 'ansible_quiet_config' in CFG.settings: - facts_env['ANSIBLE_CONFIG'] = CFG.settings['ansible_quiet_config'] - - return run_ansible(playbook, inventory_file, facts_env, verbose) diff --git a/utils/test/cli_installer_tests.py b/utils/test/cli_installer_tests.py index 673997c42..2259f3416 100644 --- a/utils/test/cli_installer_tests.py +++ b/utils/test/cli_installer_tests.py @@ -384,6 +384,7 @@ deployment: storage: """ + class UnattendedCliTests(OOCliFixture): def setUp(self): @@ -402,8 +403,9 @@ class UnattendedCliTests(OOCliFixture): load_facts_mock.return_value = (mock_facts, 0) run_playbook_mock.return_value = 0 - config_file = self.write_config(os.path.join(self.work_dir, - 'ooinstall.conf'), SAMPLE_CONFIG % 'openshift-enterprise') + config_file = self.write_config( + os.path.join(self.work_dir, 'ooinstall.conf'), + SAMPLE_CONFIG % 'openshift-enterprise') self.cli_args.extend(["-c", config_file, "install"]) result = self.runner.invoke(cli.cli, self.cli_args) @@ -481,8 +483,9 @@ class UnattendedCliTests(OOCliFixture): load_facts_mock.return_value = (MOCK_FACTS, 0) run_playbook_mock.return_value = 0 - config_file = self.write_config(os.path.join(self.work_dir, - 'ooinstall.conf'), SAMPLE_CONFIG % 'openshift-enterprise') + config_file = self.write_config( + os.path.join(self.work_dir, 'ooinstall.conf'), + SAMPLE_CONFIG % 'openshift-enterprise') self.cli_args.extend(["-c", config_file, "install"]) result = self.runner.invoke(cli.cli, self.cli_args) @@ -490,16 +493,18 @@ class UnattendedCliTests(OOCliFixture): load_facts_args = load_facts_mock.call_args[0] self.assertEquals(os.path.join(self.work_dir, "hosts"), - load_facts_args[0]) - self.assertEquals(os.path.join(self.work_dir, - "playbooks/byo/openshift_facts.yml"), load_facts_args[1]) + load_facts_args[0]) + self.assertEquals( + os.path.join(self.work_dir, "playbooks/byo/openshift_facts.yml"), + load_facts_args[1]) env_vars = load_facts_args[2] - self.assertEquals(os.path.join(self.work_dir, - '.ansible/callback_facts.yaml'), + self.assertEquals( + os.path.join(self.work_dir, '.ansible/callback_facts.yaml'), env_vars['OO_INSTALL_CALLBACK_FACTS_YAML']) self.assertEqual('/tmp/ansible.log', env_vars['ANSIBLE_LOG_PATH']) # If user running test has rpm installed, this might be set to default: - self.assertTrue('ANSIBLE_CONFIG' not in env_vars or + self.assertTrue( + 'ANSIBLE_CONFIG' not in env_vars or env_vars['ANSIBLE_CONFIG'] == cli.DEFAULT_ANSIBLE_CONFIG) # Make sure we ran on the expected masters and nodes: @@ -515,8 +520,9 @@ class UnattendedCliTests(OOCliFixture): load_facts_mock.return_value = (MOCK_FACTS, 0) run_playbook_mock.return_value = 0 - config_file = self.write_config(os.path.join(self.work_dir, - 'ooinstall.conf'), merged_config) + config_file = self.write_config( + os.path.join(self.work_dir, 'ooinstall.conf'), + merged_config) self.cli_args.extend(["-c", config_file, "install"]) result = self.runner.invoke(cli.cli, self.cli_args) @@ -526,9 +532,9 @@ class UnattendedCliTests(OOCliFixture): inventory = configparser.ConfigParser(allow_no_value=True) inventory.read(os.path.join(self.work_dir, 'hosts')) self.assertEquals('root', - inventory.get('OSEv3:vars', 'ansible_ssh_user')) + inventory.get('OSEv3:vars', 'ansible_ssh_user')) self.assertEquals('openshift-enterprise', - inventory.get('OSEv3:vars', 'deployment_type')) + inventory.get('OSEv3:vars', 'deployment_type')) # Check the masters: self.assertEquals(1, len(inventory.items('masters'))) @@ -546,13 +552,13 @@ class UnattendedCliTests(OOCliFixture): @patch('ooinstall.openshift_ansible.run_main_playbook') @patch('ooinstall.openshift_ansible.load_system_facts') - def test_variant_version_latest_assumed(self, load_facts_mock, - run_playbook_mock): + def test_variant_version_latest_assumed(self, load_facts_mock, run_playbook_mock): load_facts_mock.return_value = (MOCK_FACTS, 0) run_playbook_mock.return_value = 0 - config_file = self.write_config(os.path.join(self.work_dir, - 'ooinstall.conf'), SAMPLE_CONFIG % 'openshift-enterprise') + config_file = self.write_config( + os.path.join(self.work_dir, 'ooinstall.conf'), + SAMPLE_CONFIG % 'openshift-enterprise') self.cli_args.extend(["-c", config_file, "install"]) result = self.runner.invoke(cli.cli, self.cli_args) @@ -569,19 +575,18 @@ class UnattendedCliTests(OOCliFixture): inventory = configparser.ConfigParser(allow_no_value=True) inventory.read(os.path.join(self.work_dir, 'hosts')) self.assertEquals('openshift-enterprise', - inventory.get('OSEv3:vars', 'deployment_type')) + inventory.get('OSEv3:vars', 'deployment_type')) @patch('ooinstall.openshift_ansible.run_main_playbook') @patch('ooinstall.openshift_ansible.load_system_facts') - def test_variant_version_preserved(self, load_facts_mock, - run_playbook_mock): + def test_variant_version_preserved(self, load_facts_mock, run_playbook_mock): load_facts_mock.return_value = (MOCK_FACTS, 0) run_playbook_mock.return_value = 0 config = SAMPLE_CONFIG % 'openshift-enterprise' config = '%s\n%s' % (config, 'variant_version: 3.3') - config_file = self.write_config(os.path.join(self.work_dir, - 'ooinstall.conf'), config) + config_file = self.write_config( + os.path.join(self.work_dir, 'ooinstall.conf'), config) self.cli_args.extend(["-c", config_file, "install"]) result = self.runner.invoke(cli.cli, self.cli_args) @@ -597,7 +602,7 @@ class UnattendedCliTests(OOCliFixture): inventory = configparser.ConfigParser(allow_no_value=True) inventory.read(os.path.join(self.work_dir, 'hosts')) self.assertEquals('openshift-enterprise', - inventory.get('OSEv3:vars', 'deployment_type')) + inventory.get('OSEv3:vars', 'deployment_type')) # unattended with bad config file and no installed hosts (without --force) @patch('ooinstall.openshift_ansible.run_main_playbook') @@ -606,25 +611,28 @@ class UnattendedCliTests(OOCliFixture): load_facts_mock.return_value = (MOCK_FACTS, 0) run_playbook_mock.return_value = 0 - config_file = self.write_config(os.path.join(self.work_dir, - 'ooinstall.conf'), BAD_CONFIG % 'openshift-enterprise') + config_file = self.write_config( + os.path.join(self.work_dir, 'ooinstall.conf'), + BAD_CONFIG % 'openshift-enterprise') self.cli_args.extend(["-c", config_file, "install"]) result = self.runner.invoke(cli.cli, self.cli_args) self.assertEquals(1, result.exit_code) - self.assertTrue("You must specify either an ip or hostname" + self.assertTrue( + "You must specify either an ip or hostname" in result.output) - #unattended with three masters, one node, and haproxy + # unattended with three masters, one node, and haproxy @patch('ooinstall.openshift_ansible.run_main_playbook') @patch('ooinstall.openshift_ansible.load_system_facts') def test_quick_ha_full_run(self, load_facts_mock, run_playbook_mock): load_facts_mock.return_value = (MOCK_FACTS_QUICKHA, 0) run_playbook_mock.return_value = 0 - config_file = self.write_config(os.path.join(self.work_dir, - 'ooinstall.conf'), QUICKHA_CONFIG % 'openshift-enterprise') + config_file = self.write_config( + os.path.join(self.work_dir, 'ooinstall.conf'), + QUICKHA_CONFIG % 'openshift-enterprise') self.cli_args.extend(["-c", config_file, "install"]) result = self.runner.invoke(cli.cli, self.cli_args) @@ -636,15 +644,16 @@ class UnattendedCliTests(OOCliFixture): self.assertEquals(6, len(hosts)) self.assertEquals(6, len(hosts_to_run_on)) - #unattended with two masters, one node, and haproxy + # unattended with two masters, one node, and haproxy @patch('ooinstall.openshift_ansible.run_main_playbook') @patch('ooinstall.openshift_ansible.load_system_facts') def test_quick_ha_only_2_masters(self, load_facts_mock, run_playbook_mock): load_facts_mock.return_value = (MOCK_FACTS_QUICKHA, 0) run_playbook_mock.return_value = 0 - config_file = self.write_config(os.path.join(self.work_dir, - 'ooinstall.conf'), QUICKHA_2_MASTER_CONFIG % 'openshift-enterprise') + config_file = self.write_config( + os.path.join(self.work_dir, 'ooinstall.conf'), + QUICKHA_2_MASTER_CONFIG % 'openshift-enterprise') self.cli_args.extend(["-c", config_file, "install"]) result = self.runner.invoke(cli.cli, self.cli_args) @@ -653,15 +662,16 @@ class UnattendedCliTests(OOCliFixture): self.assert_result(result, 1) self.assertTrue("A minimum of 3 masters are required" in result.output) - #unattended with three masters, one node, but no load balancer specified: + # unattended with three masters, one node, but no load balancer specified: @patch('ooinstall.openshift_ansible.run_main_playbook') @patch('ooinstall.openshift_ansible.load_system_facts') def test_quick_ha_no_lb(self, load_facts_mock, run_playbook_mock): load_facts_mock.return_value = (MOCK_FACTS_QUICKHA, 0) run_playbook_mock.return_value = 0 - config_file = self.write_config(os.path.join(self.work_dir, - 'ooinstall.conf'), QUICKHA_CONFIG_NO_LB % 'openshift-enterprise') + config_file = self.write_config( + os.path.join(self.work_dir, 'ooinstall.conf'), + QUICKHA_CONFIG_NO_LB % 'openshift-enterprise') self.cli_args.extend(["-c", config_file, "install"]) result = self.runner.invoke(cli.cli, self.cli_args) @@ -670,15 +680,16 @@ class UnattendedCliTests(OOCliFixture): self.assert_result(result, 1) self.assertTrue('No master load balancer specified in config' in result.output) - #unattended with three masters, one node, and one of the masters reused as load balancer: + # unattended with three masters, one node, and one of the masters reused as load balancer: @patch('ooinstall.openshift_ansible.run_main_playbook') @patch('ooinstall.openshift_ansible.load_system_facts') def test_quick_ha_reused_lb(self, load_facts_mock, run_playbook_mock): load_facts_mock.return_value = (MOCK_FACTS_QUICKHA, 0) run_playbook_mock.return_value = 0 - config_file = self.write_config(os.path.join(self.work_dir, - 'ooinstall.conf'), QUICKHA_CONFIG_REUSED_LB % 'openshift-enterprise') + config_file = self.write_config( + os.path.join(self.work_dir, 'ooinstall.conf'), + QUICKHA_CONFIG_REUSED_LB % 'openshift-enterprise') self.cli_args.extend(["-c", config_file, "install"]) result = self.runner.invoke(cli.cli, self.cli_args) @@ -686,15 +697,16 @@ class UnattendedCliTests(OOCliFixture): # This is not a valid configuration: self.assert_result(result, 1) - #unattended with preconfigured lb + # unattended with preconfigured lb @patch('ooinstall.openshift_ansible.run_main_playbook') @patch('ooinstall.openshift_ansible.load_system_facts') def test_quick_ha_preconfigured_lb(self, load_facts_mock, run_playbook_mock): load_facts_mock.return_value = (MOCK_FACTS_QUICKHA, 0) run_playbook_mock.return_value = 0 - config_file = self.write_config(os.path.join(self.work_dir, - 'ooinstall.conf'), QUICKHA_CONFIG_PRECONFIGURED_LB % 'openshift-enterprise') + config_file = self.write_config( + os.path.join(self.work_dir, 'ooinstall.conf'), + QUICKHA_CONFIG_PRECONFIGURED_LB % 'openshift-enterprise') self.cli_args.extend(["-c", config_file, "install"]) result = self.runner.invoke(cli.cli, self.cli_args) @@ -706,6 +718,7 @@ class UnattendedCliTests(OOCliFixture): self.assertEquals(6, len(hosts)) self.assertEquals(6, len(hosts_to_run_on)) + class AttendedCliTests(OOCliFixture): def setUp(self): @@ -720,17 +733,18 @@ class AttendedCliTests(OOCliFixture): load_facts_mock.return_value = (MOCK_FACTS, 0) run_playbook_mock.return_value = 0 - cli_input = build_input(hosts=[ - ('10.0.0.1', True, False), - ('10.0.0.2', False, False), - ('10.0.0.3', False, False)], - ssh_user='root', - variant_num=1, - confirm_facts='y', - storage='10.1.0.1',) + cli_input = build_input( + hosts=[ + ('10.0.0.1', True, False), + ('10.0.0.2', False, False), + ('10.0.0.3', False, False)], + ssh_user='root', + variant_num=1, + confirm_facts='y', + storage='10.1.0.1',) self.cli_args.append("install") - result = self.runner.invoke(cli.cli, self.cli_args, - input=cli_input) + result = self.runner.invoke( + cli.cli, self.cli_args, input=cli_input) self.assert_result(result, 0) self._verify_load_facts(load_facts_mock) @@ -741,12 +755,12 @@ class AttendedCliTests(OOCliFixture): inventory = configparser.ConfigParser(allow_no_value=True) inventory.read(os.path.join(self.work_dir, 'hosts')) - self.assert_inventory_host_var(inventory, 'nodes', '10.0.0.1', - 'openshift_schedulable=False') - self.assert_inventory_host_var_unset(inventory, 'nodes', '10.0.0.2', - 'openshift_schedulable=True') - self.assert_inventory_host_var_unset(inventory, 'nodes', '10.0.0.3', - 'openshift_schedulable=True') + self.assert_inventory_host_var( + inventory, 'nodes', '10.0.0.1', 'openshift_schedulable=False') + self.assert_inventory_host_var_unset( + inventory, 'nodes', '10.0.0.2', 'openshift_schedulable=True') + self.assert_inventory_host_var_unset( + inventory, 'nodes', '10.0.0.3', 'openshift_schedulable=True') # interactive with config file and some installed some uninstalled hosts @patch('ooinstall.openshift_ansible.run_main_playbook') @@ -762,15 +776,16 @@ class AttendedCliTests(OOCliFixture): load_facts_mock.return_value = (mock_facts, 0) run_playbook_mock.return_value = 0 - cli_input = build_input(hosts=[ - ('10.0.0.1', True, False), - ('10.0.0.2', False, False), + cli_input = build_input( + hosts=[ + ('10.0.0.1', True, False), + ('10.0.0.2', False, False), ], - add_nodes=[('10.0.0.3', False, False)], - ssh_user='root', - variant_num=1, - confirm_facts='y', - storage='10.0.0.1',) + add_nodes=[('10.0.0.3', False, False)], + ssh_user='root', + variant_num=1, + confirm_facts='y', + storage='10.0.0.1',) self.cli_args.append("install") result = self.runner.invoke(cli.cli, self.cli_args, @@ -781,7 +796,6 @@ class AttendedCliTests(OOCliFixture): self.assertTrue('scaleup' in result.output) self.assert_result(result, 1) - @patch('ooinstall.openshift_ansible.run_main_playbook') @patch('ooinstall.openshift_ansible.load_system_facts') def test_fresh_install_with_config(self, load_facts_mock, run_playbook_mock): @@ -830,26 +844,27 @@ class AttendedCliTests(OOCliFixture): # exp_hosts_to_run_on_len=2, # force=False) - #interactive multimaster: one more node than master + # interactive multimaster: one more node than master @patch('ooinstall.openshift_ansible.run_main_playbook') @patch('ooinstall.openshift_ansible.load_system_facts') def test_ha_dedicated_node(self, load_facts_mock, run_playbook_mock): load_facts_mock.return_value = (MOCK_FACTS_QUICKHA, 0) run_playbook_mock.return_value = 0 - cli_input = build_input(hosts=[ - ('10.0.0.1', True, False), - ('10.0.0.2', True, False), - ('10.0.0.3', True, False), - ('10.0.0.4', False, False)], - ssh_user='root', - variant_num=1, - confirm_facts='y', - master_lb=('10.0.0.5', False), - storage='10.1.0.1',) + cli_input = build_input( + hosts=[ + ('10.0.0.1', True, False), + ('10.0.0.2', True, False), + ('10.0.0.3', True, False), + ('10.0.0.4', False, False)], + ssh_user='root', + variant_num=1, + confirm_facts='y', + master_lb=('10.0.0.5', False), + storage='10.1.0.1',) self.cli_args.append("install") - result = self.runner.invoke(cli.cli, self.cli_args, - input=cli_input) + result = self.runner.invoke( + cli.cli, self.cli_args, input=cli_input) self.assert_result(result, 0) self._verify_load_facts(load_facts_mock) @@ -872,25 +887,26 @@ class AttendedCliTests(OOCliFixture): self.assertTrue(inventory.has_section('etcd')) self.assertEquals(3, len(inventory.items('etcd'))) - #interactive multimaster: identical masters and nodes + # interactive multimaster: identical masters and nodes @patch('ooinstall.openshift_ansible.run_main_playbook') @patch('ooinstall.openshift_ansible.load_system_facts') def test_ha_no_dedicated_nodes(self, load_facts_mock, run_playbook_mock): load_facts_mock.return_value = (MOCK_FACTS_QUICKHA, 0) run_playbook_mock.return_value = 0 - cli_input = build_input(hosts=[ - ('10.0.0.1', True, False), - ('10.0.0.2', True, False), - ('10.0.0.3', True, False)], - ssh_user='root', - variant_num=1, - confirm_facts='y', - master_lb=('10.0.0.5', False), - storage='10.1.0.1',) + cli_input = build_input( + hosts=[ + ('10.0.0.1', True, False), + ('10.0.0.2', True, False), + ('10.0.0.3', True, False)], + ssh_user='root', + variant_num=1, + confirm_facts='y', + master_lb=('10.0.0.5', False), + storage='10.1.0.1',) self.cli_args.append("install") - result = self.runner.invoke(cli.cli, self.cli_args, - input=cli_input) + result = self.runner.invoke( + cli.cli, self.cli_args, input=cli_input) self.assert_result(result, 0) self._verify_load_facts(load_facts_mock) @@ -919,7 +935,9 @@ class AttendedCliTests(OOCliFixture): full_line = "%s=%s" % (a, b) tokens = full_line.split() if tokens[0] == host: - self.assertTrue(variable in tokens[1:], "Unable to find %s in line: %s" % (variable, full_line)) + self.assertTrue( + variable in tokens[1:], + "Unable to find %s in line: %s" % (variable, full_line)) return self.fail("unable to find host %s in inventory" % host) @@ -938,45 +956,46 @@ class AttendedCliTests(OOCliFixture): return self.fail("unable to find host %s in inventory" % host) - - #interactive multimaster: attempting to use a master as the load balancer should fail: + # interactive multimaster: attempting to use a master as the load balancer should fail: @patch('ooinstall.openshift_ansible.run_main_playbook') @patch('ooinstall.openshift_ansible.load_system_facts') def test_ha_reuse_master_as_lb(self, load_facts_mock, run_playbook_mock): load_facts_mock.return_value = (MOCK_FACTS_QUICKHA, 0) run_playbook_mock.return_value = 0 - cli_input = build_input(hosts=[ - ('10.0.0.1', True, False), - ('10.0.0.2', True, False), - ('10.0.0.3', False, False), - ('10.0.0.4', True, False)], - ssh_user='root', - variant_num=1, - confirm_facts='y', - master_lb=(['10.0.0.2', '10.0.0.5'], False), - storage='10.1.0.1') + cli_input = build_input( + hosts=[ + ('10.0.0.1', True, False), + ('10.0.0.2', True, False), + ('10.0.0.3', False, False), + ('10.0.0.4', True, False)], + ssh_user='root', + variant_num=1, + confirm_facts='y', + master_lb=(['10.0.0.2', '10.0.0.5'], False), + storage='10.1.0.1') self.cli_args.append("install") - result = self.runner.invoke(cli.cli, self.cli_args, - input=cli_input) + result = self.runner.invoke( + cli.cli, self.cli_args, input=cli_input) self.assert_result(result, 0) - #interactive all-in-one + # interactive all-in-one @patch('ooinstall.openshift_ansible.run_main_playbook') @patch('ooinstall.openshift_ansible.load_system_facts') def test_all_in_one(self, load_facts_mock, run_playbook_mock): load_facts_mock.return_value = (MOCK_FACTS, 0) run_playbook_mock.return_value = 0 - cli_input = build_input(hosts=[ - ('10.0.0.1', True, False)], - ssh_user='root', - variant_num=1, - confirm_facts='y', - storage='10.0.0.1') + cli_input = build_input( + hosts=[ + ('10.0.0.1', True, False)], + ssh_user='root', + variant_num=1, + confirm_facts='y', + storage='10.0.0.1') self.cli_args.append("install") - result = self.runner.invoke(cli.cli, self.cli_args, - input=cli_input) + result = self.runner.invoke( + cli.cli, self.cli_args, input=cli_input) self.assert_result(result, 0) self._verify_load_facts(load_facts_mock) @@ -990,25 +1009,25 @@ class AttendedCliTests(OOCliFixture): self.assert_inventory_host_var(inventory, 'nodes', '10.0.0.1', 'openshift_schedulable=True') - @patch('ooinstall.openshift_ansible.run_main_playbook') @patch('ooinstall.openshift_ansible.load_system_facts') def test_gen_inventory(self, load_facts_mock, run_playbook_mock): load_facts_mock.return_value = (MOCK_FACTS, 0) run_playbook_mock.return_value = 0 - cli_input = build_input(hosts=[ - ('10.0.0.1', True, False), - ('10.0.0.2', False, False), - ('10.0.0.3', False, False)], - ssh_user='root', - variant_num=1, - confirm_facts='y', - storage='10.1.0.1',) + cli_input = build_input( + hosts=[ + ('10.0.0.1', True, False), + ('10.0.0.2', False, False), + ('10.0.0.3', False, False)], + ssh_user='root', + variant_num=1, + confirm_facts='y', + storage='10.1.0.1',) self.cli_args.append("install") self.cli_args.append("--gen-inventory") - result = self.runner.invoke(cli.cli, self.cli_args, - input=cli_input) + result = self.runner.invoke( + cli.cli, self.cli_args, input=cli_input) self.assert_result(result, 0) self._verify_load_facts(load_facts_mock) @@ -1021,12 +1040,12 @@ class AttendedCliTests(OOCliFixture): inventory = configparser.ConfigParser(allow_no_value=True) inventory.read(os.path.join(self.work_dir, 'hosts')) - self.assert_inventory_host_var(inventory, 'nodes', '10.0.0.1', - 'openshift_schedulable=False') - self.assert_inventory_host_var_unset(inventory, 'nodes', '10.0.0.2', - 'openshift_schedulable=True') - self.assert_inventory_host_var_unset(inventory, 'nodes', '10.0.0.3', - 'openshift_schedulable=True') + self.assert_inventory_host_var( + inventory, 'nodes', '10.0.0.1', 'openshift_schedulable=False') + self.assert_inventory_host_var_unset( + inventory, 'nodes', '10.0.0.2', 'openshift_schedulable=True') + self.assert_inventory_host_var_unset( + inventory, 'nodes', '10.0.0.3', 'openshift_schedulable=True') # TODO: test with config file, attended add node diff --git a/utils/test/fixture.py b/utils/test/fixture.py index 873ac4a27..5c0d1d2c1 100644 --- a/utils/test/fixture.py +++ b/utils/test/fixture.py @@ -43,6 +43,7 @@ deployment: node: """ + def read_yaml(config_file_path): cfg_f = open(config_file_path, 'r') config = yaml.safe_load(cfg_f.read()) @@ -105,7 +106,7 @@ class OOCliFixture(OOInstallFixture): self.assertTrue('ip' in host) self.assertTrue('public_ip' in host) - #pylint: disable=too-many-arguments + # pylint: disable=too-many-arguments def _verify_get_hosts_to_run_on(self, mock_facts, load_facts_mock, run_playbook_mock, cli_input, exp_hosts_len=None, exp_hosts_to_run_on_len=None, @@ -152,7 +153,7 @@ class OOCliFixture(OOInstallFixture): self.assertEquals(exp_hosts_to_run_on_len, len(hosts_to_run_on)) -#pylint: disable=too-many-arguments,too-many-branches,too-many-statements +# pylint: disable=too-many-arguments,too-many-branches,too-many-statements def build_input(ssh_user=None, hosts=None, variant_num=None, add_nodes=None, confirm_facts=None, schedulable_masters_ok=None, master_lb=('', False), storage=None): @@ -190,7 +191,7 @@ def build_input(ssh_user=None, hosts=None, variant_num=None, else: inputs.append('rpm') - #inputs.append('rpm') + # inputs.append('rpm') # We should not be prompted to add more hosts if we're currently at # 2 masters, this is an invalid HA configuration, so this question # will not be asked, and the user must enter the next host: @@ -224,13 +225,13 @@ def build_input(ssh_user=None, hosts=None, variant_num=None, inputs.append('y') inputs.append('1') # Add more nodes i = 0 - for (host, is_master, is_containerized) in add_nodes: + for (host, _, is_containerized) in add_nodes: inputs.append(host) if is_containerized: inputs.append('container') else: inputs.append('rpm') - #inputs.append('rpm') + # inputs.append('rpm') if i < len(add_nodes) - 1: inputs.append('y') # Add more hosts else: diff --git a/utils/test/oo_config_tests.py b/utils/test/oo_config_tests.py index 5651e6e7a..80cdbe618 100644 --- a/utils/test/oo_config_tests.py +++ b/utils/test/oo_config_tests.py @@ -107,6 +107,7 @@ deployment: node: """ + class OOInstallFixture(unittest.TestCase): def setUp(self): @@ -133,13 +134,12 @@ class OOInstallFixture(unittest.TestCase): return path - class OOConfigTests(OOInstallFixture): def test_load_config(self): - cfg_path = self.write_config(os.path.join(self.work_dir, - 'ooinstall.conf'), SAMPLE_CONFIG) + cfg_path = self.write_config( + os.path.join(self.work_dir, 'ooinstall.conf'), SAMPLE_CONFIG) ooconfig = OOConfig(cfg_path) self.assertEquals(3, len(ooconfig.deployment.hosts)) @@ -155,26 +155,25 @@ class OOConfigTests(OOInstallFixture): def test_load_bad_config(self): - cfg_path = self.write_config(os.path.join(self.work_dir, - 'ooinstall.conf'), CONFIG_BAD) + cfg_path = self.write_config( + os.path.join(self.work_dir, 'ooinstall.conf'), CONFIG_BAD) try: OOConfig(cfg_path) assert False except OOConfigInvalidHostError: assert True - def test_load_complete_facts(self): - cfg_path = self.write_config(os.path.join(self.work_dir, - 'ooinstall.conf'), SAMPLE_CONFIG) + cfg_path = self.write_config( + os.path.join(self.work_dir, 'ooinstall.conf'), SAMPLE_CONFIG) ooconfig = OOConfig(cfg_path) missing_host_facts = ooconfig.calc_missing_facts() self.assertEquals(0, len(missing_host_facts)) # Test missing optional facts the user must confirm: def test_load_host_incomplete_facts(self): - cfg_path = self.write_config(os.path.join(self.work_dir, - 'ooinstall.conf'), CONFIG_INCOMPLETE_FACTS) + cfg_path = self.write_config( + os.path.join(self.work_dir, 'ooinstall.conf'), CONFIG_INCOMPLETE_FACTS) ooconfig = OOConfig(cfg_path) missing_host_facts = ooconfig.calc_missing_facts() self.assertEquals(2, len(missing_host_facts)) @@ -182,8 +181,8 @@ class OOConfigTests(OOInstallFixture): self.assertEquals(3, len(missing_host_facts['10.0.0.3'])) def test_write_config(self): - cfg_path = self.write_config(os.path.join(self.work_dir, - 'ooinstall.conf'), SAMPLE_CONFIG) + cfg_path = self.write_config( + os.path.join(self.work_dir, 'ooinstall.conf'), SAMPLE_CONFIG) ooconfig = OOConfig(cfg_path) ooconfig.save_to_disk() @@ -191,8 +190,6 @@ class OOConfigTests(OOInstallFixture): written_config = yaml.safe_load(f.read()) f.close() - - self.assertEquals(3, len(written_config['deployment']['hosts'])) for h in written_config['deployment']['hosts']: self.assertTrue('ip' in h) @@ -259,8 +256,10 @@ class HostTests(OOInstallFixture): # Given the `yaml_props` above we should see a line like this: # openshift_node_labels="{'region': 'infra'}" - node_labels_expected = '''openshift_node_labels="{'region': 'infra'}"''' # Quotes around the hash - node_labels_bad = '''openshift_node_labels={'region': 'infra'}''' # No quotes around the hash + # Quotes around the hash + node_labels_expected = '''openshift_node_labels="{'region': 'infra'}"''' + # No quotes around the hash + node_labels_bad = '''openshift_node_labels={'region': 'infra'}''' # The good line is present in the written inventory line self.assertIn(node_labels_expected, legacy_inventory_line) diff --git a/utils/test/test_utils.py b/utils/test/test_utils.py index cabeaee34..a72e429d1 100644 --- a/utils/test/test_utils.py +++ b/utils/test/test_utils.py @@ -29,7 +29,6 @@ class TestUtils(unittest.TestCase): mock.call('OO_FOO: bar'), ] - ###################################################################### # Validate ooinstall.utils.debug_env functionality |